什么时候不使用 EntityManager.flush()?

When NOT to use EntityManager.flush()?

为了同步和检索数据库生成的 ID,我不得不在几个地方调用 EntityManager.flush()

抛开性能影响,是否有理由调用flush()

换句话说,如果 does/doesn 不是 flush(),我的 (DAO, ...) 方法的调用方是否有任何可观察到的差异?

我的场景是在支持我们的 JPA 开发人员的框架上下文中。我会提供一些功能,这些功能可能需要也可能不需要 flush() 在调用层次结构的深处。这些功能的用户是否必须知道 if/when 刷新发生,或者它是一个私有实现细节,对调用者没有明显影响?

调用 flush() 将持久性上下文与数据库同步。这主要是必需的 - 如果需要查询命中(通过 JPQL 等)。

稍后在数据库的调用堆栈中,如果持久性上下文包含其状态可能受查询结果影响的任何对象的脏值,则需要同步这些对象。事实上,JPA 查询的默认 FlushModeTypeAUTO

When queries are executed within a transaction, if FlushModeType.AUTO is set on the Query or TypedQuery object, or if the flush mode setting for the persistence context is AUTO (the default) and a flush mode setting has not been specified for the Query or TypedQuery object, the persistence provider is responsible for ensuring that all updates to the state of all entities in the persistence context which could potentially affect the result of the query are visible to the processing of the query. The persistence provider implementation may achieve this by flushing those entities to the database or by some other means.

因此,只要您通过对象的状态而不是 JPA 查询来查询对象,并且这些查询的结果不依赖于脏状态,那么调用 flush 对性能不利,因为它涉及重复的脏状态检查就在提交时。

@Adams 提到了他使用 OpenJPA 的经历,其中 flush 破坏了一些东西,所以我猜不同的实现在这里有问题。

性能几乎概括了调用 flush 的大部分原因 "not"。 Flush 是一种强制将所有更改语句立即推送到数据库的方法,而不是累积并作为更大的批次发送。它可能很有用,因为某些事务可能非常大,需要清除以释放内存,并强制按照特定顺序将更新放入数据库。

除了性能和提供程序特定问题之外,不调用 flush 的唯一其他原因是特定于应用程序的,例如当某些更改可能违反数据库约束并需要稍后进一步修改时。