为了同步并检索数据库生成的ID,我觉得我很难在几个地方调用EntityManager.flush()
。
除了性能影响之外,还有不调用flush()
的原因吗?
换句话说,如果我的(DAO,...)方法的调用者没有flush()
,是否存在任何可观察到的差异?
我的场景是在支持JPA开发人员的框架环境中。我会在调用层次结构深处的某个地方提供一些可能需要flush()
可能需要的功能。这些函数的用户是否必须知道是否/何时发生刷新,或者它是否是私有实现细节而对调用者没有明显影响?
答案 0 :(得分:3)
对flush()
的调用将持久性上下文与数据库同步。这主要是必需的 - 如果需要查询(通过JPQL等)。
稍后在调用堆栈中到数据库,如果持久化上下文包含状态可能受查询结果影响的任何对象的脏值,则需要同步这些对象。实际上,JPA查询的默认FlushModeType
为AUTO
在事务中执行查询时,如果是FlushModeType.AUTO 在Query或TypedQuery对象上设置,或者如果是刷新模式设置 持久化上下文是AUTO(默认)和刷新模式 尚未为Query或TypedQuery对象指定设置 持久性提供程序负责确保所有更新 持久化上下文中所有实体的状态都可以 可能会影响查询结果的可见性 处理查询。持久性提供程序实现可以 通过将这些实体刷新到数据库或由某些实现来实现此目的 其他方式。
因此,只要您通过其状态查询对象而不是JPA查询,并且这些查询的结果不依赖于脏状态,那么性能调用刷新是不好的,因为它涉及重复的脏状态检查而不仅仅是在提交时间。
@Adams提到了他在使用OpenJPA时的经验,其中flush打破了一些东西,所以我想不同的实现在这里有问题。
答案 1 :(得分:2)
性能几乎总结了“不”调用flush的大部分原因。 Flush是一种强制所有更改语句立即被推送到数据库的方法,而不是累积并作为更大的批处理发送。它可能很有用,因为某些事务可能非常大并且需要清除以释放内存,以及强制某个订单使您的更新进入数据库。
除性能和提供程序特定问题外,不调用flush的唯一原因是特定于应用程序,例如某些更改可能违反数据库约束并需要稍后进行进一步修改。