在 JPA 中刷新的确切目的是什么

2022-09-02 04:33:13

一些令人困惑的解释:flush();刷新是将基础持久性存储与保存在 memory.it 更新或插入到正在运行的事务中的表中的持久状态的过程,但它可能不会提交这些更改。

如果更改无论如何都要在提交后保留在数据库中,那么为什么要在代码中间刷新。

在运行刷新后,如果对托管对象进行了任何更改,那么这将引发异常,还是这些更改将被同步,然后变为perisist。如果它们被同步,那么为什么首先要刷新。


答案 1

从理论上讲,您(作为JPA的用户)永远不应该(或在绝对罕见的情况下)处于呼叫的情况。flush()

刷新是将基础持久性存储与内存中保存的持久状态同步的过程

换句话说,在数据库上没有任何反应之前,在数据库上实际调用的所有插入,更新,删除或任何语句。刷新是由事务的提交或某些类型的数据库读取引起的。例如,如果执行 JPQL 查询,则必须执行 a 才能从数据库中获得正确的结果。但是,这非常值得了解,并且完全由您的JPA实现处理。flush()flush()flush()

在某些情况下,您可能希望自己控制此刷新,然后可以使用 调用它。flush()

编辑以回答评论中的问题:

并非每次读取都需要刷新,请考虑以下方案(一个事务):

  1. 阅读一个人Person p = em.find(Person.class, 234)
  2. 更新人员p.setAge(31)
  3. 读取建筑物Building b = em.find(Building.class, 123
  4. 使用 JPQL 查询读取建筑物select b from Building b where b.id = 123

自动刷新仅在 4.之前发生,因为 Eclipselink 无法确定您要读取的内容,因此在进行此读取之前,该人的年龄必须在数据库中是最新的。在3之前。不需要刷新,因为Eclipselink知道一个人的更新不会影响建筑物。

要使用乐观锁定,您必须实现它。在此处阅读注释:https://blogs.oracle.com/carolmcdonald/entry/jpa_2_0_concurrency_and。没有这个,您的实体将不会使用乐观锁定,并且“上次更新获胜”。@Version


答案 2

当事务提交时,实体管理器将为您执行刷新。在某些情况下,与在容器管理的事务中处理乐观锁定一样,您可能需要手动调用 flush 方法来捕获和处理特定的锁定异常。


推荐