org.hibernate.HibernateException: identifier of an instance of XXX was altered from X to X

本文探讨了Hibernate在级联保存过程中出现的主键更改错误及解决方案。通过调整cascade选项,解决了级联保存时的主键冲突问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hibernate报错: org.hibernate.HibernateException: identifier of an instance of XXX was altered from X to X
这个错误是因为Hibernate在保存的时候因为级联保存导致的,我的项目中具体问题如下: 我在保存ServerProduct的时候报错,分析原因如下:
其中我在ProductProject上的限制cascade=CascadeType.ALL意思是级联保存的时候包括全部行为,那么就会级联保存他中的级联类:masterDbaData和backupDbaData。所以会报错user的主键不能又111改成222。 

于是还不是很清楚级联更新的我将所有的cascade都改成了cascade = CascadeType.DETACH,这样DETACH就相当于级联evict操作,此时发现虽然不报错了,但是发现保存各个user的信息都是不成功的。
原因:evict方法会从session缓存中清楚当前对象时,会级联清除所有关联对象,所以保存不成功

接下来我又将所有的cascade都改成了cascade = CascadeType.ALL,保存报错,错误类似于:user中的company不为空
原因:当我修改了serverProduct中涉及到人的操作时,比如userA他原来信息会被更新为都为空,因为是级联更新,同时我的这个user类上面company做了限制@NotNull,所有会报错。

最终解决方法: 

这样在保存serverProduct的时候会级联保存productProject但是不会去级联保存我们的user类。

总结:
是否级联被注解字段里面的对象。可选值:javax.persistence.CascadeType.PERSIST, MERGE, REMOVE, REFRESH, DETACH, ALL。可选其中的一个或多个,选一个时,花括号可用可不用

PERSIST:级联session的persist操作。假设Student类和teachers字段的@ManyToMany注解上配置有cascade = {CascadeType.PERSIST},那么,当stu1对象set了一个teachers集合(这个集合里面的对象都是瞬态的),持久化这个stu1d对象时,这个集合里面的所有瞬态对象都会被级联持久化到数据库  
MERGE:级联merge操作
REMOVE  级联remove操作。
REFRESH 级联refresh操作。
DETACH  级联evict操作。
ALL 级联以上所有操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值