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

Jim*_*myB 5 java jpa flush entitymanager eclipselink

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

除了性能影响之外,还有什么理由不打电话flush()呢?

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

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

Sha*_*dra 4

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

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

当在事务中执行查询时,如果在 Query 或 TypedQuery 对象上设置了 FlushModeType.AUTO,或者如果持久性上下文的刷新模式设置为 AUTO(默认)并且尚未为 Query 或 TypedQuery 指定刷新模式设置。 TypedQuery 对象,持久性提供程序负责确保持久性上下文中所有实体的状态的所有更新(可能会影响查询结果)对查询处理可见。持久性提供者实现可以通过将这些实体刷新到数据库或通过一些其他方式来实现这一点。

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

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

  • 显然,即使在 [`COMMIT`](http://docs.oracle.com/javaee/6/api/javax/persistence/FlushModeType.html#COMMIT) 刷新模式下,“提供程序可能会在其他时间刷新,但不需要。” (2认同)