2013-04-09 45 views
-1

JPA 2.0规范(JSR 317)说:什么是JPQL查询和JPA持久化上下文环境中的批量更新?

The persistence context is not synchronized with the result of the bulk update or delete. 

究竟是什么一个散装更新?

在我看来,[或更确切地说应该是]“批量更新”和“定期更新”之间的区别。我想相信批量更新是更新多个实体的更新。因此,应该有一个更新没有归类为“批量”,这是一项只针对一个实体的更新操作。在这种情况下,该操作是否更新第一级缓存是非常重要的。

该规范从来没有解决这个问题,或给出了“批量更新”表达式的明确定义。我也不能在这个主题上找到任何其他来源。我尽我所能测试应用程序托管的资源本地实体管理器(使用EclipseLink 2.3.2.v20111125-r10461),并且可以确认持久性上下文确实已过时,即使我们执行仅针对一个实体的更新查询。 JPA提供者也没有调用我附加到测试类的实体监听器。

我在阅读JPA 2.0规范后认为,这只适用于“批量更新”,即针对具有受影响行的多个实体的更新查询大于1。但是,通过前面描述的测试结果我开始认为没有像“定期更新”那样的东西,所有更新查询“批量更新”。

这个故事告诉我们,如果这是真的,是只推缓存的内容时,我们做EntityManager#findEntityManager#mergeEntityManager#remove和JPQL选择查询(Query#getResultListQuery#getSingleResult)。但是,如果我们执行了JPQL更新或删除查询(Query#executeUpdate),我们应该而不是推高速缓存。为了Java EE新手的好处,应该添加它,以使其他应用程序进程和直接数据库调用(JDBC)也可以使缓存失效。无论这是真的还是不行,还有一件事我不明白:

这是什么设计,为什么不应该JPA提供同步持久化上下文和/或他的二级缓存背后的原理是什么?我的第一个猜测是性能方面的原因,但是再次,我不知道。

如果你知道任何东西,给我!

+0

Downvoter保健佳品他的推理? – 2014-04-23 08:34:41

回答

1

“BULK UPDATE”显然是使用查询如“UPDATE MyEntity SET field1 = val1 WHERE field2 < 345”(正如批量删除是删除查询)的更新。 正常更新是您使用setter直接更新托管实体的字段的位置。

理由:好批量更新的整点是没有对象加载到内存中,或锻炼身体,如果任何受影响的对象已经进行管理。你可能会发现,大多数JPA实现将赶在执行批量更新了二级缓存的可能受影响的对象。

+0

是的,但那是问题!你认为'UPDATE实体E设置e.myId =“XXX” WHERE e.myId =“YYY''是一个** **批量更新时,我们知道'myId'是唯一约束的主键?当然,这个查询只会影响一行。因此,如果规范说** bulk **更新,那么受影响的行数大于1的查询,那么像我描述的那样的查询应该与缓存同步!这似乎是共识,那里的所有更新和删除语句将使缓存失效,但这可能不是规范的要求? – 2013-04-10 10:53:50

+0

性能上的好处。就像我当时所想的那样,但是我在发布的文档中找不到任何关于它的内容。 – 2013-04-10 10:54:38

+0

我认为任何通过查询更新为“批量”(即使它们没有更新超过1个对象),因为它有一个通用的过滤器。各个实现可能会检查更新的逻辑,以决定是否更新一个以上的对象,并决定如果管理将更改应用于该对象,但不需要规范IIRC – DataNucleus 2013-04-10 11:06:44

0

批量更新的定义JPQL DELETEUPDATE操作。执行这些操作后,必须采取具体行动,以确保您的持久化上下文与数据库同步。

批量更新相当直接映射到SQL命令,这是直接的SQL服务器上执行。在适当的情况下,这会更快,特别是在更新数百或数千行时更是如此。服务器不会显示哪些行被编辑(只有多少),因此将数据库的状态与任何活动的持久性上下文同步将会非常昂贵。使用批量更新命令一次更改一行或几行是效率低下的,并且通常会带来麻烦,因此无济于事。 EntityManager是你的朋友,它想帮忙。

如果你希望在你的持久化上下文管理的批量更改,使用EntityManager而不是使用Query执行他们...的费用将是相等的,它是发现它一直是实体的价格/将单独更改。

我的批量更新的理解是,他们应该在单独的事务,那么一个新的EntityManager应该使用之后进行。我的编码风格,在交易的范围EntityManager符合这个好...但如果你把它的一切使用一个超级EntityManager它可能是更为繁重。