最近在写SSH整合时出现了 deleted object would be re-saved by cascade这个错误
我的Hibernate关系映射文件如下
<many-to-one name="dept" class="cn.pb.pojo.Dept" lazy="false" >
<column name="DEPTNO" />
</many-to-one>
<set name="emps" inverse="true" lazy="fasle" cascade="save-update,merge,delete">
<key>
<column name="DEPTNO" />
</key>
<one-to-many class="cn.pb.pojo.Emp" />
</set>
然后通过百度找到了如下几种的解决方法
- 方法1 删除Set方的cascade
- 方法2 解决关联关系后,再删除
- many.getOne().getManys().remove(many); //在所关联的一方的set中移走当前要删除的对象
- manyDao.delete(many);
- 方法3 在many-to-one方增加cascade 但值不能是none
以OneToMany为例
1、如果Many端存在于One端的集合中,直接删除Many,就会抛出delete object would be re-saved by cascade的异常
出现这种情况的原因是在一对多的一方没有让其延迟加载
<set name="emps" inverse="true" lazy="fasle" cascade="save-update,merge,delete">
<key>
<column name="DEPTNO" precision="2" scale="0" />
</key>
<one-to-many class="cn.pb.pojo.Emp" />
</set>
解决方法:lazy属性设置为true,或者是在One端的集合中先删除Many端,然后再在Hibernate中删除Many端
注意:如果直接删除One端,由于主外键关系肯定会引发“Cannot delete or update a parent row:aforeign key constraint fails”的异常
若按照第三种方案,很显然在删除Many的一方之后,One的一方中的数据也会被删除,这样给数据的完整性带来的很大的隐患
而使用第一种方案在编写数据访问层的代码时需要手动的维护数据的完整性,显然降低了开发的效率
所以当遇到上述问题时,个人推荐使用第二种解决方案