博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate中的cascade和inverse
阅读量:6307 次
发布时间:2019-06-22

本文共 2835 字,大约阅读时间需要 9 分钟。

hot3.png

这两个属性都用于一多对或者多对多的关系中。而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中摘取的。

 

 

 

我们知道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. }  
 

转载于:https://my.oschina.net/roockee/blog/97285

你可能感兴趣的文章
Android中Handler引起的内存泄露
查看>>
原产地政策,jsonp跨域
查看>>
HDU 1143 Tri Tiling(递归)
查看>>
ffmpeg参数具体解释
查看>>
记一次公司仓库数据库服务器死锁过程
查看>>
Oracle 11g password过期被锁定报道 ORA-28000 the account is locked
查看>>
【Struts2学习笔记(2)】Action默认值和配置Action于result各种转发类型
查看>>
轨磁条简介
查看>>
(算法)交错的字符串
查看>>
hdu 5471(状压DP or 容斥)
查看>>
oracle.jdbc.driver.OracleDriver和oracle.jdbc.OracleDriver这两个驱动的区别
查看>>
NSQ部署
查看>>
git常用命令记录
查看>>
IBM发布新一代云计算工具包MobileFirst Foundation
查看>>
唯品会HDFS性能挑战和优化实践
查看>>
大规模学习该如何权衡得失?解读NeurIPS 2018时间检验奖获奖论文
查看>>
大厂前端高频面试问题与答案精选
查看>>
我们用5分钟写了一个跨多端项目
查看>>
Visual Studio 15.4发布,新增多平台支持
查看>>
有赞透明多级缓存解决方案(TMC)设计思路
查看>>