`

hibernate inverse属性

阅读更多
inverse的含义说得玄乎点是控制翻转,说得普通就是关系的维护有谁来做。
因为在关系数据库里面table和table之间是通过外键维护关系的(1-1,1-n),对于1-n的情况,
很显然,外键由N的一方来维护比有1的一方来维护要好,这就是OOP中的has a的关系,
用hibernate进行数据存取的时候如果在集合属性里面不设置inverse=true,那么在保存n后,
hibernate会更新外键----update TEST.Groups set PARENT_ID=? where id=?(PARENT_ID
是外键)。然而这是多余的


 Hibernate一对多双向关联及inverse的作用

       在测试Hibernate的一对多双向关联映射时,碰到很有趣的问题,跟inverse属性直接相关。

1、People.hbm.xml

<hibernate-mapping  default-lazy="false">  
   
<class name="com.persistent.People" table="people">     
     
<id name="id" column="peopleId" unsaved-value="0">    
        
<generator class="increment">        
        
</generator>    
     
</id>     
     
<property name="name" column="name"></property>     
     
<set name="addresses" cascade="save-update">
        
<key column="peopleId" not-null="true" />
        
<one-to-many class="com.persistent.Address"/>
     
</set>     
   
</class>
</hibernate-mapping>

2、Address.hbm.xml

<hibernate-mapping>
  
<class name="com.persistent.Address" table="address">  
    
<id name="id" column="addressId" unsaved-value="0">
        
<generator class="increment">
        
</generator>
    
</id>    
    
<many-to-one name="people" column="peopleId" insert="false" update="false"></many-to-one>    
    
<property name="addressName" column="addressName"></property>    
    
<property name="codeNumber" column="codeNumber"></property>    
  
</class>  
</hibernate-mapping>

3、People.java和Address.java

public class People {    
  
private long id;
  
private String name;
  
private Set addresses = new HashSet();
  ...
}


public class Address {    
  
private long id;
  
private People people;
  
private String addressName;
  
private String codeNumber;
  ...
}
        

4、数据库结构

  people表:{peopleId,name}

  address表:{addressId,peopleId,addressName,codeNumber}

5、测试代码

People people = new People();
people.setName(
"linda");
Address address 
= new Address();
address.setAddressName(
"yunnan");
address.setCodeNumber(
"564123");
address.setPeople(people);
people.getAddresses().add(address);
Session session 
= HibernateSessionFactory.getSession();
session.beginTransaction();
session.save(people);
session.getTransaction().commit();

6、运行结果

      上面测试代码运行起来正确:

Hibernate: select max(peopleId) from people
Hibernate: select max(addressId) from address
Hibernate: insert into people (name, peopleId) values (?, ?)
Hibernate: insert into address (addressName, codeNumber, peopleId, addressId) values (?, ?, ?, ?)
Hibernate: update address set peopleId=? where addressId=?

      如果将People.hbm.xml映射改写一下:

<set name="addresses" cascade="save-update" inverse="true">
        
<key column="peopleId" not-null="true" />
        
<one-to-many class="com.persistent.Address"/>
</set>

      不同之处在于添加了inverse="true",结果:
Hibernate: select max(peopleId) from people
Hibernate: select max(addressId) from address
Hibernate: insert into people (name, peopleId) values (?, ?)
Hibernate: insert into address (addressName, codeNumber, addressId) values (?, ?, ?)

      可以看到,peopleId并没有写入到关联的address当中,数据库address表中相应记录的peopleId字段为空。

7、分析

      在Hibernate中,术语inverse是反转的意思,在关联关系中,inverse="false"为主控方,由主控方负责维护对象的关联关系。所以上面的映射文件改动之后,address为主控方,people为被控方,但是测试代码只进行了一个保存操作session.save(people),这是针对people的,因此无法正确级联保存address。而原来的映射文件中(虽然没有明确指明,Hibernate默认inverse="false"),people为主控方,因此保存people时它会保证关联的address的正确保存。

      也就是说,Hibernate仅仅按照主控方对象的状态的变化来同步更新数据库。按照原来的映射文件,people.getAddresses().add(address),即主控方对象的状态发生了改变,因此数据库会跟着对象状态的变化来同步更新数据库;而address.setPeople(people),即被控方对象的状态发生了改变,它是不能触发对象和数据库的同步更新的。

分享到:
评论

相关推荐

    Hibernate中cascade与inverse属性详解

    Hibernate中cascade与inverse属性详解

    Hibernate中cascade与inverse属性详解.doc

    于Hibernate中 cascade 与 inverse 的理解。 您买的Hibernate书是哪一本呢? 孙卫琴的精通Hibernate,还是 深入浅出Hibernate还是那本。。。 我是两本都买了,总体来说还可以,但是,有的地方讲的比较书面化,比如...

    Hibernate中Cascade和inverse的区别

    Hibernate中Cascade和inverse的区别,讲解的很详细

    hibernate多对多双向关联

    &lt;set name="roles" table="t_user_role"&gt;&lt;br&gt; &lt;key column="userid"/&gt;&lt;br&gt; &lt;many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/&gt; &lt;/set&gt;&lt;br&gt; table属性必须和单向关联中table的 ...

    inverse 例子

    hibernate中inverse作用。我是一个Hibernate的初学者,前两天刚刚研究了一下inverse属性,有所心得。故把自己的小例子贴出来,与大家共享。

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

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

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     7.2.1 元素的inverse属性  7.2.2 级联删除  7.2.3 父子关系  7.3 映射一对多双向自身关联关系  7.4 改进持久化类  7.5 小结  7.6 思考题 第8章 通过Hibernate操纵对象(上)  8.1 Java对象在JVM中的生命...

    hibernate 3中的缓存小结

    -- Hibernate只会缓存对象的简单属性的值, 要缓存集合属性,必须在集合元素中也加入子元素 而Hibernate仅仅是把与当前持久对象关联的对象的OID存放到缓存中。 如果希望把整个关联的对象的所有数据都存入缓存, 则要...

    Hibernate注释大全收藏

    Hibernate 可以对类的属性或者方法进行注解。属性对应field类别,方法的 getXxx()对应property类别。 定义表 通过 @Table 为实体Bean指定对应数据库表,目录和schema的名字。 @Entity @Table(name="tbl_sky") ...

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

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

    hibernate总结

    i. 如果不加fetch关键字,则hibernate不会抓取关系属性,但会遍历关系属性所对应的表 ii. 不加fetch关键字时,select 要指定返回的对象,否则它要返回数组 iii. 条件:持久化类之间有关系属性映射 Hibernate级联...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     7.2.1 元素的inverse属性  7.2.2 级联删除  7.2.3 父子关系  7.3 映射一对多双向自身关联关系  7.4 改进持久化类  7.5 小结  7.6 思考题 第8章 通过Hibernate操纵对象(上)  8.1 Java对象在JVM中的生命...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     7.2.1 元素的inverse属性  7.2.2 级联删除  7.2.3 父子关系  7.3 映射一对多双向自身关联关系  7.4 改进持久化类  7.5 小结  7.6 思考题 第8章 通过Hibernate操纵对象(上)  8.1 Java对象在JVM中的生命...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     7.2.1 元素的inverse属性  7.2.2 级联删除  7.2.3 父子关系  7.3 映射一对多双向自身关联关系  7.4 改进持久化类  7.5 小结  7.6 思考题 第8章 通过Hibernate操纵对象(上)  8.1 Java对象在JVM中的生命...

    hibernate学习5之one-to-many双向关联.docx

    如果在”一“一端维护一对多关联关系,hibernate会发出多余的udpate语句,所以我们一般在多的一端来维护关联关系。 加上inverse="true"这个属性,就可以强制在多的一端维护关系了。

    Hibernate_Annotation关联映射

    如果是双向关联,其中一段必须定义为Owner,另一端必须定义为inverse(在对关联表进行更新操作时这一端将被忽略) @Entity() public class Employer implements Serializable { private Integer id; private ...

    JAVA自学之路

    7:XML (XML/XSL、XSLT/DTD、SCHEMA等基础的概念、关于Java的编程可以暂时扔在一边) 8:Hibernate ...普通属性映射 关联关系映射 Native SQL inverse lazy cascade 继承关系映射 HQL 性能优化 一级

    BOS 技术整理

    rc/main/resource 提供 config.properties 外部属性文件、log4j.properties 日志配置文件 配置文件如下: applicationContext.xml  struts2 注解 类上 @ParentPackage 包继承谁? extends=”struts-default...

Global site tag (gtag.js) - Google Analytics