JPA/hibernate:在命名查询后忽略持久化

JPA/hibernate:在命名查询后忽略持久化,hibernate,jpa,Hibernate,Jpa,以下java代码: fooDAO.resetField(); // ...namedQuery foo.setField(true); fooDAO.persist(foo); foo.field是一个布尔属性 resetField()执行一个命名查询,将所有db行中的字段设置为FALSE 如果foo.field最初为FALSE,hibernate将执行两个SQL查询,即setField/persist组合的命名查询和更新查询。 但是如果foo.field最初为TRUE,则只执行第一个SQL查

以下java代码:

fooDAO.resetField(); // ...namedQuery
foo.setField(true);
fooDAO.persist(foo);
foo.field
是一个布尔属性

resetField()
执行一个命名查询,将所有db行中的字段设置为FALSE

如果
foo.field
最初为FALSE,hibernate将执行两个SQL查询,即setField/persist组合的命名查询和更新查询。 但是如果
foo.field
最初为TRUE,则只执行第一个SQL查询,将所有行中的字段设置为FALSE,第二个SQL查询将被忽略。。。为什么?

让我引用《批量更新和删除》一章中ProJPA 2书的作者

…坚持 不会更新上下文以反映操作的结果。批量操作以SQL形式针对 数据库,绕过持久性上下文的内存中结构。(…)开发人员只能依赖于在大容量存储之后检索的实体 操作完成。(…)这意味着批量操作 应该在事务中单独执行,还是作为事务中的第一个操作

在您的情况下,我建议您重新安排代码,将批量更新包含在自己的事务中,或者在尝试更改它之前,在
foo
上调用
EntityManager.refresh()


您所描述的是一种预期行为,因为在批量更新之后,
foo
实例会过时。它存在于内存中,但并不反映现实。

需要查看更多代码才能得出结论。您给出的测试用例应该可以正常工作。它应该执行两个查询。