hibernate级联删除问题
有用户和用户组两个表,需要使用hibernate做级联删除。映射文件如下:
Groups.hbm.xml
原本要做的是,删除用户组时将其下所属的用户全部删除;删除用户时,不对用户组进行更改。
结果过执行报错:deleted object would be re-saved by cascade (removedeleted object from associations)
感觉可能是cascade的配置问题,修改了下发现还是报错。后来我将Groups映射文件中<set>元素的lazy属性设置为true。删除成功!但是这样由于是延迟加载,就没法在页面中通过groups来获取User集合中的对象了(本来是想统计用户组中用户成员的个数)。于是还得修改。
查了文档弄明白了怎么回事。
原来cascade属性在lazy=true的时候不起作用(集合中对象还没初始化)。所以在删除User的时候,就不会触发对关联关系的维护。
而当lazy=false的时候,由于我们设置了cascade,那么删除User的时候会触发关系维护,此时虽然在user中已经将对应的Groups属性设置为null(删除前会先将外键设置为null)。但是由于Groups中的Set中仍然还保持着我们删除的User对象,所以触发关系维护的时候,这个User对象又会被重新保存到数据库中。造成了前面出现的异常。
当然,如果我们删除Groups的时候,如果没有将Set的cascade设置为all或delete,那么就会报错: Cannot delete or update a parent row:a foreign key constraint fails,因为groups删除了,User中对groups的外键引用怎么办?
解决的办法就是,如果不需要在groups中直接获取Set中的User对象,那么就把lazy设置为true就可以了。不设置cascade也可以,不过删除groups的时候就可能有问题了。或者通过代码,在删除之前将关联关系解除。
public void delete(User entity) {
entity.getGroups().getUsers().remove(entity);
entity.setGroups(null);
userDao.delete(entity);
}