使用EntityManager/Hibernate进行批量更新



我正在使用Hibernate,并且(例如(有一个包含10000个条目的Employee实体。假设他们中有1000人的工资是4000,我想增加到5000。我很难找到一种有效的方法来做到这一点。

通过获取所有员工并更新相关条目在代码中进行操作似乎是无效的、缓慢的,而且似乎还会导致";批量更新从更新"返回了意外的行计数;某些情况下的错误。

因此,按照这里的建议,使用本机查询似乎更好,但您需要更新Hibernate缓存,以查看下一个请求的更改:

Employee e = em.find(Employee.class, <id ???>);
em.flush();
em.detach(e);
em.createNativeQuery("UPDATE employee SET salery = 5000 where salery = 4000") 
.executeUpdate();

但是,我不知道如何在发出本机更新查询之前分离实体。em.find调用的第二个参数似乎是单个实体的id?但是Emloyees在整个应用程序中都有使用,那么我应该如何知道要分离哪些呢?有没有一种方法可以分离所有员工(例如em.detachAll(Employee.class((,或者我应该在一个循环中迭代所有1000名员工并单独分离他们?

我也对解决我最初问题的其他解决方案持开放态度。

在代码中通过获取所有员工并更新相关条目来完成这项工作似乎无效、缓慢。。。

正如hibernate文档中所述:

Hibernate本机查询语言和JPQL(Java持久性查询语言(都支持批量UPDATEDELETE

因此,您可以这样编写查询:

int updatedEntities = entityManager.createQuery(
"update Employee e " +
"set e.salery = :newSalery " +
"where e.salery = :oldSalery" )
.setParameter("oldSalery", 4000)
.setParameter("newSalery", 5000)
.executeUpdate();

还请注意,正如JPA 2.0规范第4.10节所述,应注意何时执行UPDATEDELETE语句:

执行批量更新或删除操作时应注意,因为这些操作可能会导致数据库和活动持久性上下文中的实体之间不一致通常,批量更新和删除操作只能在新的持久性上下文中的事务内执行,或者在获取或访问其状态可能受到此类操作影响的实体之前执行

最新更新