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
<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
<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
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.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映射改写一下:
<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书是哪一本呢? 孙卫琴的精通Hibernate,还是 深入浅出Hibernate还是那本。。。 我是两本都买了,总体来说还可以,但是,有的地方讲的比较书面化,比如...
Hibernate中Cascade和inverse的区别,讲解的很详细
<set name="roles" table="t_user_role"><br> <key column="userid"/><br> <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/> </set><br> table属性必须和单向关联中table的 ...
hibernate中inverse作用。我是一个Hibernate的初学者,前两天刚刚研究了一下inverse属性,有所心得。故把自己的小例子贴出来,与大家共享。
本章介绍一对多关联关系的映射方法,重点介绍inverse属性和cascade属性的用法。本章还将介绍通过Hibernate API来保存、修改和删除具有关联关系的对象的方法。 7.1 建立多对一的单向关联关系 148 7.1.1 [many-to-...
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只会缓存对象的简单属性的值, 要缓存集合属性,必须在集合元素中也加入子元素 而Hibernate仅仅是把与当前持久对象关联的对象的OID存放到缓存中。 如果希望把整个关联的对象的所有数据都存入缓存, 则要...
Hibernate 可以对类的属性或者方法进行注解。属性对应field类别,方法的 getXxx()对应property类别。 定义表 通过 @Table 为实体Bean指定对应数据库表,目录和schema的名字。 @Entity @Table(name="tbl_sky") ...
本章介绍一对多关联关系的映射方法,重点介绍inverse属性和cascade属性的用法。本章还将介绍通过Hibernate API来保存、修改和删除具有关联关系的对象的方法。 7.1 建立多对一的单向关联关系 148 7.1.1 [many-to-...
i. 如果不加fetch关键字,则hibernate不会抓取关系属性,但会遍历关系属性所对应的表 ii. 不加fetch关键字时,select 要指定返回的对象,否则它要返回数组 iii. 条件:持久化类之间有关系属性映射 Hibernate级联...
7.2.1 元素的inverse属性 7.2.2 级联删除 7.2.3 父子关系 7.3 映射一对多双向自身关联关系 7.4 改进持久化类 7.5 小结 7.6 思考题 第8章 通过Hibernate操纵对象(上) 8.1 Java对象在JVM中的生命...
7.2.1 元素的inverse属性 7.2.2 级联删除 7.2.3 父子关系 7.3 映射一对多双向自身关联关系 7.4 改进持久化类 7.5 小结 7.6 思考题 第8章 通过Hibernate操纵对象(上) 8.1 Java对象在JVM中的生命...
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会发出多余的udpate语句,所以我们一般在多的一端来维护关联关系。 加上inverse="true"这个属性,就可以强制在多的一端维护关系了。
如果是双向关联,其中一段必须定义为Owner,另一端必须定义为inverse(在对关联表进行更新操作时这一端将被忽略) @Entity() public class Employer implements Serializable { private Integer id; private ...
7:XML (XML/XSL、XSLT/DTD、SCHEMA等基础的概念、关于Java的编程可以暂时扔在一边) 8:Hibernate ...普通属性映射 关联关系映射 Native SQL inverse lazy cascade 继承关系映射 HQL 性能优化 一级
rc/main/resource 提供 config.properties 外部属性文件、log4j.properties 日志配置文件 配置文件如下: applicationContext.xml struts2 注解 类上 @ParentPackage 包继承谁? extends=”struts-default...