`

Hibernate中的cascade和inverse

阅读更多

这两个属性都用于一多对或者多对多的关系中。而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);   
  11.   
  12.   
  13. 1. 如果cascade="all"且inverse="false"时:   
  14.   
  15.   
  16. 此时可以看到log里面:   
  17.   
  18. // 执行对father的插入   
  19. Hibernate: insert into father (name) values (?)   
  20.   
  21. // cascade = 'all',所以进行级联操作   
  22. Hibernate: insert into child (name, fatherid) values (?, ?)   
  23. Hibernate: insert into child (name, fatherid) values (?, ?)   
  24.   
  25. // inverse = 'false',由father来维护关系(可以看到这些操作是多余的)   
  26. Hibernate: update child set fatherid =? where ID=?   
  27. Hibernate: update child set fatherid =? where ID=?   
  28.   
  29.   
  30. 2. 如果cascade = "none" 且 inverse = "false":   
  31.   
  32.   
  33. // 执行对father的插入   
  34. Hibernate: insert into father (name) values (?)   
  35.   
  36. // inverse='false',所以更新关系   
  37. Hibernate: update child set fatherid =? where ID=?   
  38.   
  39. // 但由于cascade='none',child并未插入数据库,导致如下exception   
  40. org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance   
  41.   
  42.   
  43. 3. 如果cascade = "all" 且 inverse = "true"  
  44.   
  45. // 执行对father的插入   
  46. Hibernate: insert into father (name) values (?)   
  47.   
  48. // cascade='all',执行对child的插入   
  49. Hibernate: insert into child (name, fatherid) values (?, ?)   
  50. Hibernate: insert into child (name, fatherid) values (?, ?)   
  51.   
  52. // 但由于inverse='true',所以未有对关系的维护。但由于一对多的关系中,关系本身在“多”方的表中。所以,无需更新   
  53. 关系。   
  54.   
  55.   
  56. 4. 如果cascade = "none" 且 inverse = "true"  
  57.   
  58. // 只执行对father的插入   
  59. Hibernate: insert into father (name) values (?)   
  60.   
  61. 可以看到,对于一对多关系,关系应由“多”方来维护(指定“一”方的inverse为true),并且应在“一”方指定相应的级联操作。  
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类中。

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. }  

http://zfsn.iteye.com/blog/512096

分享到:
评论

相关推荐

    Hibernate中cascade和inverse应用

    在 Hibernate 框架中,`cascade` 和 `inverse` 是两个重要的概念,它们主要用于管理对象之间的持久化关系,特别是涉及到一对一(one-to-one)、一对多(one-to-many)和多对多(many-to-many)关系时。这两个属性都...

    Hibernate中cascade与inverse属性详解

    Hibernate中cascade与inverse属性详解

    hibernate 级联(cascade和inverse)一对多

    在Java的持久化框架Hibernate中,级联操作(Cascade)和反转(Inverse)是两个重要的概念,它们主要用于管理对象关系模型中的关联关系。在一对多的关系中,这些特性可以帮助简化数据操作,提高代码的可读性和维护性...

    hibernate inverse和cascade的详细讲解

    ### Hibernate Inverse 和 Cascade 的详细讲解 #### 一、引言 在ORM(Object-Relational Mapping)领域,Hibernate作为一款流行的Java持久层框架,它提供了丰富的API和配置选项来帮助开发者实现对象与数据库表之间...

    Hibernate中Inverse和Cascade的区别.html

    Hibernate中Inverse和Cascade的区别.html

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

    在探讨Hibernate框架中的级联操作(cascade)与控制权反转(inverse)之前,我们需要先对Hibernate有一个基本的理解。Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为Java应用提供了一种将对象模型映射到...

    关联映射cascade,inverse讲解

    本篇将深入讲解“cascade”和“inverse”这两个重要的概念,以及它们在实际应用中的作用。 首先,让我们理解一下“关联映射”。在Hibernate中,关联映射允许我们将Java对象与数据库表的记录进行关联。例如,一个...

    inverse和cascade使用阐述

    在IT领域,"inverse"和"cascade"是两个常见的概念,尤其在数据库设计、软件工程以及数据处理中。这两个术语通常与关系型数据库中的外键约束、对象关系映射(ORM)工具,以及某些编程框架的特性相关。下面将详细阐述这...

    关于cascade和inverse属性[文].pdf

    总结起来,`cascade`和`inverse`是Hibernate中用于管理对象关联关系的重要属性,它们共同确保了数据的一致性和操作的便捷性。在实际应用中,需要根据业务逻辑和性能需求,合理设置这两个属性,以达到最佳的数据库...

    hibernate集合映射inverse和cascade详解.txt

    `inverse`和`cascade`属性是Hibernate集合映射中非常重要的概念,它们帮助开发者更灵活地控制实体之间的关系以及操作的级联行为。合理地使用这两个属性,不仅可以简化代码,还能提高程序的性能和健壮性。然而,不当...

    hibernate_配置cascade_及all-delete-orphan.doc

    ### Hibernate中的Cascade选项详解 #### 一、概述 在Hibernate框架中,cascade选项提供了一种管理实体间关联的便捷方式,使得对一个实体的操作能够自动地应用到与之相关的其他实体上。这对于处理复杂的数据库关系...

    JavaEE学习笔记之Hibernate表关系之一对多(inverse详解)

    `inverse`属性是Hibernate中用于控制关联维护权的重要参数,它的主要作用在于确定关联关系的更新和删除操作由哪一方负责。默认情况下,关联的维护权在"多"端,即子实体,这意味着当子实体发生变化时,如增加、删除或...

    Hibernate学习笔记和资料

    hibernate中一对一,一对多,多对多关系的配置,延迟加载,cascade,inverse hibernate查询方式概述,HQL查询,QBC查询,分页,结果集封装方式 ,高级查询 查询的优化,一级缓存,二级缓存,批量查询,注解方式

    Hibernate开发租房系统2 源码

    描述提到“使用cascade和inverse优化区和街道关联关系”,这意味着我们将深入理解Hibernate的cascade和inverse属性,以及它们在双向一对多关联关系中的应用。 Hibernate是Java领域中广泛使用的对象关系映射(ORM)...

    Hibenate cascade

    在Hibernate中,`cascade`和`inverse`是两个重要的概念,它们涉及到对象之间的关系管理和数据持久化。 **1. Hibernate Cascade** `cascade`属性主要用于控制对象间的级联操作。当在主对象上执行保存、更新、删除等...

    hibernate

    根据提供的文件信息,我们可以深入探讨Hibernate框架中的几个关键概念,特别是`fetch`, `lazy`, `cascade`, 和 `inverse`关键字的使用与理解。这四个概念在处理对象关系映射(ORM)时非常重要,尤其是在Java环境下...

    Hibernate常见问题

    理解并正确使用Hibernate的`cascade`和`inverse`属性对于优化数据操作和避免数据一致性问题至关重要。在实际开发中,应根据业务逻辑和数据模型谨慎设定这些属性,以确保数据操作的正确性和高效性。

    inverse 例子

    在Hibernate这个强大的对象关系映射(ORM)框架中,`inverse`属性是一个非常重要的概念,它主要用于管理关联关系的维护责任。在这个例子中,我们将会深入理解`inverse`属性的作用,并通过一个简单的测试案例——`...

Global site tag (gtag.js) - Google Analytics