Java 为什么我看不到通过使用Spring数据JPA的更新查询发布的更改?

Java 为什么我看不到通过使用Spring数据JPA的更新查询发布的更改?,java,spring,jpa,spring-data,Java,Spring,Jpa,Spring Data,我有以下服务: @Service public class CamelService { @Transactional public aCamelThing() { Camel camel = this.camelRepository.findOne(1); System.out.println(camel.getCamelName()); // prints "normalCamel" // simple h

我有以下服务:

@Service
public class CamelService {

    @Transactional
    public aCamelThing() {

          Camel camel = this.camelRepository.findOne(1);

          System.out.println(camel.getCamelName());  // prints "normalCamel"

          // simple hql set field 'camelName'
          int res = this.camelRepository.updateCamelName(1,"superCamel!");

          Camel camelWithNewName = this.camelRepository.findOne(1);

          System.out.println(camelWithNewName .getCamelName());  // prints "normalCamel" ?!?!?

    } 
}
你知道我怎样才能实现第二个println将要打印的目标吗:“superCamel!”?
(将对新事务的第二次调用分开并不理想)。

您认为这种方法可以正常工作的原因很简单:JPA就是这样定义的

我假设您触发了对
updateCamelName(…)
的更新查询。JPA规范规定了以下更新和删除操作:

持久性上下文与批量更新或删除的结果不同步

在执行批量更新或删除操作时应谨慎,因为它们可能导致数据库和活动持久性上下文中的实体之间的不一致。通常,批量更新和删除操作只应在新持久性上下文中的事务内执行,或者在获取或访问其状态可能受此类操作影响的实体之前执行

这意味着,如果需要查看此类操作的更改,则需要执行以下操作:

  • 完成此操作后,请清除
    EntityManager
    Spring Data JPA的
    @修改
    注释有一个
    自动清除
    标志,默认为
    。如果设置为true,调用query方法将自动清除
    EntityManager
    (顾名思义。请谨慎使用,因为它将有效地删除所有尚未刷新到数据库的挂起更改
  • 在存储库上调用
    findOne(…)
    EntityManager
    重新获取实体的新实例似乎是一种合理的方法,因为这大致转化为
    EntityManager.find(…)
    。请注意,这可能仍然会影响持久性提供程序上配置的二级缓存

  • 解决这一问题的最安全方法是——正如规范所建议的那样——仅对批量操作使用更新查询,并在默认情况下退回到“加载实体、更改、合并”方法。

    不确定updateCamelName在做什么(可能发出HQL查询?)。但是您至少需要刷新您的更改并可能清除存储库,否则您将获得已检索的实体。还有,为什么不简单地用名称更新
    camel
    ,并将其存储?!除了M.Deinum所说的updateCamelName还应提交事务。该方法是否用@Transactional注释Deinum,我试图更新repository.flush(),但最后一次发现仍然没有带来新名称。为什么我不简单地更新对象?我的实际使用案例比我发布的要复杂得多,只是为了简单。Dhanush,该方法是事务性的,那么为什么要更新存储库呢?