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

时间:2015-06-08 12:51:58

标签: java jpa eclipselink entitymanager flush

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

除了性能影响之外,还有调用flush()的原因吗?

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

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

2 个答案:

答案 0 :(得分:3)

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

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

  

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

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

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

答案 1 :(得分:2)

性能几乎总结了“不”调用flush的大部分原因。 Flush是一种强制所有更改语句立即被推送到数据库的方法,而不是累积并作为更大的批处理发送。它可能很有用,因为某些事务可能非常大并且需要清除以释放内存,以及强制某个订单使您的更新进入数据库。

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