以下java代码:
fooDAO.resetField(); // ...namedQuery
foo.setField(true);
fooDAO.persist(foo);
foo.field
是一个布尔属性。
resetField()
执行一个命名查询,在所有数据库行中将字段设置为FALSE。
如果foo.field
最初为FALSE,则hibernate执行2个SQL查询,即。命名查询和setField / persist组合的更新查询。
但是如果foo.field
最初为TRUE,则只执行第一个SQL查询,将所有行中的字段设置为FALSE,第二个SQL查询将被忽略! ......为什么?
答案 0 :(得分:1)
让我引用使用批量更新和删除一章中 ProJPA 2 一书的作者。
......坚持不懈 上下文未更新以反映操作的结果。批量操作作为SQL发出 数据库,绕过持久化上下文的内存结构。(...)开发人员只能依赖于批量后检索的实体 操作完成。(...)这意味着批量操作 应该在事务中单独执行,或者是事务中的第一个操作
在您的情况下,我建议重新安排代码以在其自己的交易中附加批量更新,或者在尝试更改之前调用EntityManager.refresh()
上的foo
。
您所描述的是预期的行为,因为在批量更新后,您的foo
实例变得陈旧。它存在于记忆中,但不能反映现实。