Hibernate:寻找替代已废弃update()的仅更新存在数据的方法
解决方案
在Hibernate 5.2+版本中,Session.update()虽被标记为废弃,但你可以通过以下几种方式实现仅在实体存在时更新、不存在则抛出异常的需求:
1. 先查询实体再更新
通过Session.get()或EntityManager.find()先查询目标实体,若返回null则主动抛出异常;若实体存在,直接修改其属性(此时实体处于托管状态,事务提交时Hibernate会自动同步更新到数据库)。
示例代码:
// 使用Hibernate Session YourEntity entity = session.get(YourEntity.class, targetId); if (entity == null) { throw new javax.persistence.EntityNotFoundException("实体ID: " + targetId + " 不存在"); } // 修改实体属性 entity.setField("新值"); // 或使用JPA EntityManager YourEntity entity = entityManager.find(YourEntity.class, targetId); if (entity == null) { throw new javax.persistence.EntityNotFoundException("实体ID: " + targetId + " 不存在"); } entity.setField("新值");
2. 使用Session.lock()锁定实体
通过Session.lock()尝试锁定目标实体(需预先设置实体主键),若实体不存在,Hibernate会抛出ObjectNotFoundException;锁定成功后实体进入托管状态,修改属性即可完成更新。
示例代码:
YourEntity entity = new YourEntity(); entity.setId(targetId); try { // 使用悲观写锁确保实体存在并锁定 session.lock(entity, LockMode.PESSIMISTIC_WRITE); // 修改实体属性 entity.setField("新值"); } catch (org.hibernate.ObjectNotFoundException e) { throw new javax.persistence.EntityNotFoundException("实体ID: " + targetId + " 不存在", e); }
3. 使用EntityManager.getReference()获取代理
getReference()会返回实体的代理对象,当首次访问代理的属性时,Hibernate会尝试从数据库加载实体,若不存在则抛出EntityNotFoundException;后续修改代理的属性即可完成更新。
示例代码:
YourEntity entity = entityManager.getReference(YourEntity.class, targetId); // 访问任意属性触发实体加载,不存在则抛异常 entity.getField(); // 修改实体属性 entity.setField("新值");
关键说明
merge()的核心逻辑是合并实体状态:若数据库中无对应主键的实体,会执行插入操作,这是它与原update()的核心差异。- 上述方法均遵循Hibernate的持久化上下文机制,确保仅在实体存在时执行更新,完全匹配原
update()的行为。
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

