JPA未在单个交易中考虑更新

时间:2012-12-10 12:15:33

标签: java hibernate jpa

在事务服务方法中,我循环查询数据库以获得具有条件的实体A的前10个。

我从列表中更新每个A实体,使它们不再符合条件,并调用flush()以确保进行更改。

循环中对查询的第二次调用返回完全相同的A实体集。

为什么不考虑实体的刷新变化?

我正在使用JPA 2.0和Hibernate 4.1.7。 与Hibernate相同的过程似乎只是起作用。 我已经关闭了二级缓存和查询缓存,但没有用。

我使用的是一个相当简单的配置,JpaTransactionManager,Spring over JPA over Hibernate。使用@Transactional注释的主要方法。

代码将是这样的:

do {
    modelList = exportContributionDao.getContributionListToExport(10);
    for (M m : modelList) {
        //export m to a file
    m. (false);
    super.flush();
    }
} while (modelList.size() == 10);

对于循环的每次迭代,Dao方法总是返回相同的10个结果,JPA没有考虑更新的“isToBeExported”属性。

我不是想解决问题,而是想了解为什么JPA在这里的行为不符合预期。 我希望这是一个“经典”问题。 毫无疑问,如果在每次迭代时提交交易,它将被解决。

ASAIK,缓存L1,即具有Hibernate作为底层JPA提供者的会话,应该是最新的,并且第二次迭代查询应该考虑更新的实体,即使这些更改尚未持久化。 所以我的问题是:为什么不是这样?配置错误或知道行为?

2 个答案:

答案 0 :(得分:1)

Flush不一定提交数据库上的更改。你想达到什么目的?根据我的理解,你做了s.th.喜欢:

  1. 循环实体
  2. 在循环中,更改实体
  3. 在实体上调用'flush'
  4. 再次阅读该实体
  5. 你想知道为什么数据库没有改变数据?
  6. 如果这是正确的,为什么要重新阅读更改而不使用这些元素?离开交易后,更改将自动保持持久。

答案 1 :(得分:0)

这肯定会奏效。

这是我们的配置问题。

对于这个问题道歉,我们很难发现原因,但我希望答案至少对某些人有用:

JPA肯定考虑了对单个交易中的实体所做的更改。