如何解决使用 EntityManager / Hibernate 批量更新
我正在使用 Hibernate,并且(例如)有一个 Employee
实体,其中包含 10000 个条目。假设其中 1000 人的薪水为 4000,我想增加到 5000。我很难找到有效的方法来做到这一点。
通过获取所有员工并更新相关条目在代码中执行此操作似乎无效、缓慢,并且在某些情况下似乎还会导致“批量更新从更新返回意外的行数”错误。
因此建议使用本机查询似乎更好here,但是您需要更新 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 documentation 中所述:
Hibernate 原生查询语言和 JPQL(Java 持久性查询语言)都支持 bulk UPDATE
和 DELETE
。
因此,您可以像这样编写查询:
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 节中所述,应注意何时执行 UPDATE
或 DELETE
语句:
执行批量更新或删除操作时应谨慎,因为它们可能会导致数据库和活动持久化上下文中的实体之间出现不一致。 一般来说,批量更新和删除操作只能在新的持久化上下文中的事务中执行,或者在获取或访问其状态可能受此类操作影响的实体之前执行。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。