Hibernate中的cascade和inverse

来源:互联网 发布:六扇门调查知乎 编辑:程序博客网 时间:2024/06/02 09:51

这两个属性都用于一多对或者多对多的关系中。而inverse特别是用于双向关系,在单向关系中我们并不需要。

 

Cascade代表是否执行级联操作,Inverse代表是否由己方维护关系。

 

Cascade:

 

Cascade属性的可能值有

    all: 所有情况下均进行关联操作,即save-update和delete。
    none: 所有情况下均不进行关联操作。这是默认值。
    save-update: 在执行save/update/saveOrUpdate时进行关联操作。
    delete: 在执行delete 时进行关联操作。

    all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点。比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点。

 

Inverse:

 

Inverse属性的可能值是true或者false,默认为false:

 

     false代表由己方来维护关系,true代表由对方来维护关系。在一个关系中,只能由一方来维护关系,否则会出问题(解疑中会讲到);同时也必须由一方来维护关系,否则会出现双方互相推卸责任,谁也不管。

 

一多对的例子:

 

有两个类,Father和Child,是一对多的关系。下面这段hbm配置是从Father.hbm.xml中摘取的。

 

 

<set name="children" lazy="true" cascade="all" inverse="true">    <key column="fatherid"/>    <one-to-many class="my.home.Child"/></set>  

 

我们知道cascade和inverse的值对会有四种组合的可能(在此仅先假定cascade值为none或all)。

 

有如下一段代码:

 

Java代码 复制代码
  1. FatherDao fatherDao = new FatherDao();   
  2.   
  3. Father father = new Father("David");   
  4. Child child1 = new Child("David Junior One");   
  5. Child child2 = new Child("David Junior Two");   
  6.   
  7. father.add(child1);   
  8. father.add(child2);   
  9.   
  10. fatherDao.save(father);  

 

1. 如果cascade="all"且inverse="false"时:

 

此时可以看到log里面:

 

Java代码 复制代码
  1. // 执行对father的插入   
  2. Hibernate: insert into father (name) values (?)   
  3.   
  4. // cascade = 'all',所以进行级联操作   
  5. Hibernate: insert into child (name, fatherid) values (?, ?)   
  6. Hibernate: insert into child (name, fatherid) values (?, ?)   
  7.   
  8. // inverse = 'false',由father来维护关系(可以看到这些操作是多余的)   
  9. Hibernate: update child set fatherid =? where ID=?   
  10. Hibernate: update child set fatherid =? where ID=?  

 

2. 如果cascade = "none" 且 inverse = "false":

 

Java代码 复制代码
  1. // 执行对father的插入   
  2. Hibernate: insert into father (name) values (?)   
  3.   
  4. // inverse='false',所以更新关系   
  5. Hibernate: update child set fatherid =? where ID=?   
  6.   
  7. // 但由于cascade='none',child并未插入数据库,导致如下exception   
  8. org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance  

 

3. 如果cascade = "all" 且 inverse = "true"

 

Java代码 复制代码
  1. // 执行对father的插入   
  2. Hibernate: insert into father (name) values (?)   
  3.   
  4. // cascade='all',执行对child的插入   
  5. Hibernate: insert into child (name, fatherid) values (?, ?)   
  6. Hibernate: insert into child (name, fatherid) values (?, ?)   
  7.   
  8. // 但由于inverse='true',所以未有对关系的维护。但由于一对多的关系中,关系本身在“多”方的表中。所以,无需更新   
  9. 关系。  

 

4. 如果cascade = "none" 且 inverse = "true"

 

Java代码 复制代码
  1. // 只执行对father的插入   
  2. Hibernate: insert into father (name) values (?)  

 

可以看到,对于一对多关系,关系应由“多”方来维护(指定“一”方的inverse为true),并且应在“一”方指定相应的级联操作。

 

多对多:

 

在多对多关系中,inverse可以为任何一方,没有什么区别。

 

解疑:

 

为什么在多对多中不能由双方都来维护关系了:因为这样会导致重复更新中间表的可能,报出重复值的错误。

 

那么如何在多对多的双向关联中使双方都能维护关系:最好让控制关系的那方来更新关系,如果想让另一方也来维护关系,那么只有在操作这一方的数据时“显式”更新中间表了吧。

 

注意:

 

同时注意在双向关联中,对象之间的关联跟上面提及的关系表维护没有关系。一个是对象/java层面的,一个是hibernate数据库层面的。如果你想在更新一方时,也更新另一方的对象集合,请看下面这段代码:

 

这是Person类中的一段代码,Person和Event是多对多的双向关联关系,他们在对方类中的集合分别为participants和events。关系表由Person维护,所以对象关系的维护也在Person类中,而不是Event类中。

 

Java代码 复制代码
  1. public void addToEvent(Event event) {   
  2.         this.getEvents().add(event);   
  3.         event.getParticipants().add(this);   
  4. }   
  5.   
  6. public void removeFromEvent(Event event) {   
  7.         this.getEvents().remove(event);   
  8.         event.getParticipants().remove(this);   
  9. }  

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 雷朋近视镜眼镜腿折了怎么办 近视镜眼镜腿断了该怎么办 老师把学生的眼镜打坏了怎么办 生死狙击忘了密保改不了密码怎么办 我叫mt狂猎之弓怎么办 你能利用你的弱点打击你怎么办 研控两相混合伺服电机反转怎么办? 战地一要我升级显卡驱动怎么办 刺客信条兄弟会存档损坏了怎么办 电脑上所有软件和文件被删了怎么办 电脑显示文件已打开无法删除怎么办 金立手机桌面停止运行黑屏怎么办 苹果平板电脑玩游戏黑屏闪退怎么办 电脑开机时显示无法找到入口怎么办 我的世界显示网络玩不了的怎么办啊 网页被设置成不可以到下一页怎么办 小天鹅热水器排污螺丝拧不动怎么办 葡萄霜霉严重叶片开始发焦了怎么办 上海高架gps定位信号差怎么办 老公开车技术不行还非要开怎么办 我偷了同学手机被发现应该怎么办 没满月孩孑4天没大便了怎么办 电机轴总是从皮带轮处断裂怎么办 天花板吊顶里的热水管经常坏怎么办 摩托车油箱下面的废油管漏油怎么办 大修机械压力机轴取不下来怎么办 萌侠传说账号密码没了怎么办 车子前保护杠塑料刮花了怎么办 糖猫电话手表关机了找不到了怎么办 小天才电话手表被洗衣机洗了怎么办 小天才电话手表放洗衣机洗了怎么办 小天才电话手表泡水了怎么办 小天才电话手表联不上网怎么办 肺炎用激素治疗后肚子大了怎么办 8岁以下儿童总是低烧不退怎么办? 微博里面的视频不能改变方向怎么办 朗逸导航倒车一体机死机了怎么办 乐淘乐电话手表的二维码没了怎么办 艾蔻儿童手表二维码丢了怎么办 糖猫儿童智能手表二维码丢了怎么办 海信电视用遥控器关了打不开怎么办