0

我正在使用 Hibernate 并且(例如)一个Employee具有 10000 个条目的实体。假设其中 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名员工并单独分离它们?

我也愿意接受其他解决我最初问题的解决方案。

4

1 回答 1

0

通过获取所有员工并更新相关条目在代码中执行此操作似乎无效,缓慢......

正如休眠文档中所述:

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 节所述,应注意何时执行UPDATEorDELETE语句:

执行批量更新或删除操作时应小心,因为它们可能导致数据库与活动持久性上下文中的实体之间的不一致。一般来说,批量更新和删除操作只能在新的持久性上下文中的事务内执行,或者在获取或访问其状态可能受此类操作影响的实体之前执行。

于 2021-07-03T14:58:23.183 回答