`

inverse和cascade的用法

    博客分类:
  • SSH
阅读更多

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

 

有如下一段代码:

FatherDao fatherDao = new FatherDao();   
  
Father father = new Father("David");   
Child child1 = new Child("David Junior One");   
Child child2 = new Child("David Junior Two");   
  
father.add(child1);   
father.add(child2);   
  
fatherDao.save(father);  

 

 

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

 

此时可以看到log里面:

// 执行对father的插入   
Hibernate: insert into father (name) values (?)   
  
// cascade = 'all',所以进行级联操作   
Hibernate: insert into child (name, fatherid) values (?, ?)   
Hibernate: insert into child (name, fatherid) values (?, ?)   
  
// inverse = 'false',由father来维护关系(可以看到这些操作是多余的)   
Hibernate: update child set fatherid =? where ID=?   
Hibernate: update child set fatherid =? where ID=?  

 

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

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

 

 

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

// 执行对father的插入   
Hibernate: insert into father (name) values (?)   
  
// cascade='all',执行对child的插入   
Hibernate: insert into child (name, fatherid) values (?, ?)   
Hibernate: insert into child (name, fatherid) values (?, ?)   
  
// 但由于inverse='true',所以未有对关系的维护。但由于一对多的关系中,关系本身在“多”方的表中。所以,无需更新   
关系。  

 

 

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

// 只执行对father的插入   
Hibernate: insert into father (name) values (?)  

 

 

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

 

多对多:

 

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

 

解疑:

 

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

 

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

 

注意:

 

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

 

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

 

public void addToEvent(Event event) {   
        this.getEvents().add(event);   
        event.getParticipants().add(this);   
}   
  
public void removeFromEvent(Event event) {   
        this.getEvents().remove(event);   
        event.getParticipants().remove(this);   
}  

 

分享到:
评论

相关推荐

    hibernate inverse和cascade的详细讲解

    hibernate inverse和cascade的详细讲解,相当详细全面的对inverse和cascade区别和用法的讲解

    inverse和cascade使用阐述

    NULL 博文链接:https://dtfy56924.iteye.com/blog/363917

    Hibernate_级联关系说明_-_关于cascade和inverse的用法

    inverse Hibernate_级联关系说明_-_关于cascade和inverse的用法

    Hibernate中cascade与inverse属性详解

    cascade 和inverse是Hibernate中较为难理解的两个属性,此资料详细地介绍了这两个属性的用法。

    关联映射cascade,inverse讲解

    该源程序代码可以帮助初学者迅速建立hibernate的关联映射的概念,且详细的讲解了cascade和inverse的用法,程序代码进行了详尽的描述,通俗易懂,容易上手

    java文集

    Java正则表达式 批量上传--采集 (多个文件夹) The Agile Way hibernate mapping文件中的标记详解:关系标记 ANT 安装使用及build.xml文档模板 inverse和cascade在关联更新中的作用 hibernate ...

    精通hibernate:对象持久化技术孙卫琴第二版part2

    本章介绍一对多关联关系的映射方法,重点介绍inverse属性和cascade属性的用法。本章还将介绍通过Hibernate API来保存、修改和删除具有关联关系的对象的方法。 7.1 建立多对一的单向关联关系 148 7.1.1 [many-to-...

    精通Hibernate:对象持久化技术第二版part3

    本章介绍一对多关联关系的映射方法,重点介绍inverse属性和cascade属性的用法。本章还将介绍通过Hibernate API来保存、修改和删除具有关联关系的对象的方法。 7.1 建立多对一的单向关联关系 148 7.1.1 [many-to-...

    hibernate总结

    &lt;set name="emps" inverse ="true" lazy="true" cascade="none" batch-size="2" fetch="join" &gt; Hibernate映射多对一: public class Emp implements java.io.Serializable { private Integer ...

    Hibernate注释大全收藏

    以上所有实体使用 JOINED 策略 Ferry和Boat class使用同名的主键关联(eg: Boat.id = Ferry.id), AmericaCupClass 和 Boat 关联的条件为 Boat.id = AmericaCupClass.BOAT_ID. 从父类继承的属性 @MappedSuperclass ...

    jdbc基础和参考

    ORM:使用元数据信息来描述对象和数据库之间的关系,并且能够自动实现java中持久化对象到关系型数据库中表的映射 脏检查:自动对缓存中的数据进行检查,并且选择在合适的时机和数据库之间进行交互,以保持数据的...

    Hibernate_Annotation关联映射

    使用@ManyToMany批注可定义多对多关联,同时,你也许要通过批注@JoinTable描述关联表和关联条件。如果是双向关联,其中一段必须定义为Owner,另一端必须定义为inverse(在对关联表进行更新操作时这一端将被忽略) @...

    hibernate 3中的缓存小结

    &lt;set name="products" table="products" cascade="all" inverse="true"&gt; &lt;!-- Hibernate只会缓存对象的简单属性的值, 要缓存集合属性,必须在集合元素中也加入子元素 而Hibernate仅仅是把与当前持久对象关联的...

Global site tag (gtag.js) - Google Analytics