Spring Data JPA中@PostRemove内执行Repository方法无效问题排查
问题原因及解决办法
问题原因
JPA的@PostRemove回调触发时机是数据库删除First的操作执行完成、且First实体被从持久化上下文移除之后,此时当前事务已经进入提交前的收尾阶段,Hibernate的脏数据检查流程已经完成。你在回调里修改Second实体后调用save(),Hibernate不会再自动检测到这个修改,也就不会生成UPDATE语句。
解决办法
办法一:强制触发Hibernate刷新
修改First类的postRemove()方法,在save()后手动调用flush(),强制Hibernate将修改同步到数据库:
@PostRemove public void postRemove() { second.setProp("after remove"); SecondRepository repo = MyBeanUtils.getBean(SecondRepository.class); repo.save(second); repo.flush(); // 强制刷新持久化上下文,触发UPDATE }
办法二:使用独立事务执行更新
因为当前事务即将提交,在新事务中执行更新可以确保修改被独立处理:
- 创建服务类封装带新事务的更新逻辑:
@Service public class SecondService { private final SecondRepository secondRepository; public SecondService(SecondRepository secondRepository) { this.secondRepository = secondRepository; } @Transactional(propagation = Propagation.REQUIRES_NEW) public void updateAfterFirstRemove(Second second) { second.setProp("after remove"); secondRepository.save(second); } }
- 修改
First类的postRemove()方法,调用该服务:
@PostRemove public void postRemove() { SecondService service = MyBeanUtils.getBean(SecondService.class); service.updateAfterFirstRemove(second); }
内容的提问来源于stack exchange,提问作者Ramanujan R
相关产品推荐
相关产品推荐

