在使用hibernate时,经常会碰到一级联操作的问题,一般来说,在一对多的情况下,都是应该使用级联操作的,不管是级联删除还是添加都应该支持。不过,主导方都应该是多这边,那在进行配置时,在一这边使用下面代码将主导权交给多这一边:
mappedby="xxxxx"
在这种情况下,我们在添加多这一边的数据,都是经常使用以下的代码来操作的(引用班级与学生的关系,其中班级以持久化):
Clazz c = Clazz.getDomain(班级,1);//班级 Student stu = new Student();//学生 stu.setClazz(c);//设置班级属性 stu.save();//保存操作
这样的操作,可以避免将主导权交由班级时,在进行学生信息修改时出现的过多的sql问题。然而使用以下代码时,会发生什么情况呢:
Student stu = new Student(); Clazz c = Clazz.getDomain(班级,1); stu.setClazz(c);//设置班级属性 c.getStuList().add(stu);//添加学生 c.update();//更新
简单一看,好像一定会级联保存,因为我们已经对班级强制性的更新了嘛,而且班级的stuList在属性里面也应该是dirty数据,应该被flush,触发级联操作了。然后,事实不是这样的,最终会不会保存学生信息,取决于在班级上对学生的cascade属性。只有当cascade为save_update(包括 配置成all)时,才会触发级联操作,否则会出现意想不到的问题。
具体原因就在于,实际对班级的更新操作,并不会触发对于stuList这个脏数据的判断,真正的更新操作发生在session的flush阶段,并且对于级联操作,也并不是由update进行负责的,而是由hibernate内部在flush阶段根据cascade的配置来决定是否在进行级联的。