hibernate cascade 的坑

  • 在使用hibernate的时候,因为错误的cascade和inverse的配置,对save,update,delete coding产生了一些不必要的异常,浪费时间去debug,打包测试发版等
  • 做了一些基本测试,总结如下
    • cascade的原理,使用,以及可能的坑
    • inverse使用,以及如何配合cascade
  • github上有个hibernate.demo project可做测试原码参考,参见其中com.pazu.hibernate.demo.CascadeTest.java中的测试用例和注释

cascade

why cascade & what is cascade

  • 很简单,在使用hibernate中,如果碰到1-n的关系的对象A&B,在保存的时候,正常应该是有1+n条sql去分别保存这些对象。在hibernate看来这些操作是重复的,so增加了cascade属性去解决类似的重复操作问题
  • cascade可以基本理解为,对一个pojo做指定操作时,如果该pojo中存在其他pojo的mapping关系且值非null,这个时候就会根据cascade的配置来对关联对象触发相同操作,如save,update or delete

basic usage

  • default value is nono
  • value contains : none, save-update, delete, all, orphan-delete, 最后一个并不常用
  • 如果想使用cascade来保存关联关系的话,需要明确
    • one-to-one&one-to-many的情况下(其实本质讲,one-to-one是一个unique的one-to-many,在hibernate看来),决定关联关系是否能保存的关键是fk(在这里不考虑hibernate支持的其他两种关联关系方式,如主键关联)field所在的pojo是否对应值被set,并且该pojo是否被保存了
    • 而many-to-many mapping中,无论哪一方被set,默认是都会更新关联关系的,这个取决于inverse
  • 具体可以参见cascade的test类,在上面提到过的

inverse

whats inverse

  • inverse的出现,是解决hibernate在触发cascade的情况下,有些cascade是比较低效的。假设A&B存在关联关系one-to-many,如我想使用A的cascade的save&delete,但在update A的情况下,关联B list会create n条update B的sql,and这些并不是我希望看到的。so 配置inverse可以解决这个问题

usage

  • inverse 默认值是false
  • 只在hibernate mapping的one-to-many & many-to-many collection tag上起作用,如bag,list,set等