Hibernate中inverse="true"的理解

Hibernate中inverse="true"的理解

Customer类:

Java代码

1. public class Customer {

2. private int id;

3. private String name;

4. private Set orders = new HashSet();

5. ???

6. }

即Customer类具有一个set集合属性orders,其中Order是一个普通的类:

Java代码

1. public class Order {

2. private int id;

3. private String orderName;

4. ???

5. }

数据库中表的结构:

Java代码

1. t_customer:  两个字段:id  name

2. t_order:     三个字段:id  orderName  customerid

Customer类的映射文件:Customer.hbm.xml  (Order类的映射文件忽略)

Java代码

1. <hibernate-mapping>

2.     <class name="test.Customer" table="t_customer" lazy="false">

3.         <id name="id">

4.            <generator class="native"/>

5.         </id>

6.         <property name="name"/>

7.         <set name="orders"  cascade="save-update"  lazy="false">

8.            <key column="customerid"/>

9.            <one-to-many class="test.Order"/>

10.         </set>

11.     </class>

12. </hibernate-mapping>

执行如下代码:

Java代码

1. Set orders = new HashSet();

2.

3. Order o1 = new Order();

4. o1.setOrderName("o1");

5. Order o2 = new Order();

6. o2.setOrderName("o2");

7. orders.add(o1);

8. orders.add(o2);

9.

10. Customer c = new Customer();

11. c.setName("aaa");

12. c.setOrders(orders);

13.

14. session.save(c);

此时Hibernate发出的sql语句如下:

Java代码

1. Hibernate: insert into t_customer (name) values (?)

2. Hibernate: insert into t_order (orderName) values (?)

3. Hibernate: insert into t_order (orderName) values (?)

4. Hibernate: update t_order set customerid=? where id=?

5. Hibernate: update t_order set customerid=? where id=?

查看数据库:

Java代码

1. t_customer :                    t_order:

2.

3. id   |  name                   id   |   orderName   |   customerid

4. 1       aaa                    1           o1              1

5. 2           o2              1

保存Customer对象时,首先发出insert into t_customer (name) values (?)语句将c同步到数据库,由于在<set>映射中设置cascade="save-update",所以会同时保存orders集合中的Order类型的o1,o2对象(如果没有这个设置,即cascade="save-update"),那么Hibenrate不会自动保存orders集合中的对象,那么在更新时将会抛出如下异常:

Java代码

1. Hibernate: insert into t_customer (name) values (?)

2. Hibernate: update t_order set customerid=? where id=?

3. org.hibernate.TransientObjectException: test.Order

4. ??????

抛出这一异常的原因是:<set>映射默认"inverse=fasle"即由Customer对象作为主控方,那么它要负责关联的维护工作,在这里也就是负责更新t_order表中的customerid字段的值,但由于未设置cascade="save-update",所以orders集合中的对象不会在保存customer时自动保存,因此会抛出异常(如果未设置,需要手动保存)。
现在设置cascade="save-update",同时设置inverse="true",即:

Java代码

1. ???

2. <set name="orders" cascade="save-update" inverse="true" lazy="false">

3.     <key column="customerid"/>

4.     <one-to-many class="test.Order"/>

5. </set>

6. ???

同样执行上述代码,发出如下语句:

Java代码

1. Hibernate: insert into t_customer (name) values (?)

2. Hibernate: insert into t_order (orderName) values (?)

3. Hibernate: insert into t_order (orderName) values (?)

相比上一次执行,少了两条update语句,查看数据库:

Java代码

1. t_customer :                    t_order:

2.

3. id   |  name                   id   |   orderName   |   customerid

4. 1       aaa                    1           o1              NULL

5. 2           o2              NULL

发现t_order表中customerid的值为NULL,这是由于设置了inverse="true",它意味着
Customer不再作为主控方,而将关联关系的维护工作交给关联对象Orders来完成。在保存Customer时,Customer不在关心Orders的customerid属性,必须由Order自己去维护,即设置order.setCustomer(customer);
如果需要通过Order来维护关联关系,那么这个关联关系转换成双向关联。
修改Order类代码:

Java代码

1. public class Order {

2. private int id;

3. private String orderName;

4. private Customer customer;

5. ???

6. }

Order.hbm.xml:

Java代码

1. <hibernate-mapping>

2.     <class name="test.Order" table="t_order">

3.         <id name="id">

4.            <generator class="native"/>

5.         </id>

6.         <property name="orderName"/>

7.         <many-to-one name="customer" column="customerid"/>

8.     </class>

9. </hibernate-mapping>

此时数据库中表的结构不会变化。
再次执行上述代码,发出如下sql语句:

Java代码

1. Hibernate: insert into t_customer (name) values (?)

2. Hibernate: insert into t_order (orderName, customerid) values (?, ?)

3. Hibernate: insert into t_order (orderName, customerid) values (?, ?)

发现在保存Order对象时为customerid字段赋值,因为Order对象中拥有Customer属性,对应customerid字段,查看数据库表:

Java代码

1. t_customer :                    t_order:

2.

3. id   |  name                   id   |   orderName   |   customerid

4. 1       aaa                    1           o1              NULL

5. 2           o2              NULL

发现customerid的值仍为NULL,因为在上述代码中并未设置Order对象的Customer属性值,由于设置了inverse="true",所以Order对象需要维护关联关系,所以必须进行设置,即
order.setCustomer(customer);
修改上述代码为:

Java代码

1. ???

2. Customer c = new Customer();

3.

4. Set orders = new HashSet();

5. Order o1 = new Order();

6. o1.setOrderName("o1");

7. o1.setCustomer(c);

8. Order o2 = new Order();

9. o2.setOrderName("o2");

10. o2.setCustomer(c);

11. orders.add(o1);

12. orders.add(o2);

13.

14. c.setName("aaa");

15. c.setOrders(orders);

16.

17. session.save(c);

18. ???

19.

执行上述代码,发出如下语句:

Java代码

1. Hibernate: insert into t_customer (name) values (?)

2. Hibernate: insert into t_order (orderName, customerid) values (?, ?)

3. Hibernate: insert into t_order (orderName, customerid) values (?, ?)

查看数据库:

Java代码

1. t_customer :                    t_order:

2.

3. id   |  name                   id   |   orderName   |   customerid

4. 1       aaa                    1           o1              1

5. 2           o2              1

发现已经设置了customerid的值。

原文地址:https://www.cnblogs.com/Jeely/p/11697831.html

时间: 2024-11-05 14:44:15

Hibernate中inverse="true"的理解的相关文章

一口一口吃掉Hibernate(八)——Hibernate中inverse的用法

一.Inverse是hibernate双向关系中的基本概念.inverse的真正作用就是指定由哪一方来维护之间的关联关系.当一方中指定了"inverse=false"(默认),那么那一方就有责任负责之间的关联关系,说白了就是hibernate如何生成Sql来维护关联的记录! Hibernate仅仅按照主控方对象的状态的变化来同步更新数据库.按照原来的映射文件,people.getAddresses().add(address),即主控方对象的状态发生了改变,因此数据库会跟着对象状态的变

hibernate中 inverse的用法(转载)

http://blog.csdn.net/xiaoxian8023/article/details/15380529 一.Inverse是hibernate双向关系中的基本概念.inverse的真正作用就是指定由哪一方来维护之间的关联关系.当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系,说白了就是hibernate如何生成Sql来维护关联的记录! Hibernate仅仅按照主控方对象的状态的变化来同步更新数据库.按照原来的映射文件,people.get

hibernate中inverse的用法

hibernate中inverse的用法 转自:http://blog.csdn.net/leader_lx/archive/2008/08/06/2774137.aspx 一.Inverse是hibernate双向关系中的基本概念.inverse的真正作用就是指定由哪一方来维护之间的关联关系.当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系,说白了就是hibernate如何生成Sql来维护关联的记录 Hibernate仅仅按照主控方对象的状态的变化来同

Hibernate中inverse属性与cascade属性

Hibernate集合映射中,经常会使用到"inverse"和"cascade"这两个属性.对于我这样,Hibernate接触不深和语文水平够烂的种种因素,发现这两个属性实在是难以理解,无奈只好将这个两个属性解释工作交给了Google和Baidu,查看了许多牛人的解释,加上自己在Eclipse上的调试,对"inverse"和"cascade"这两个属性有了一定的见解. "inverse"属性探究 "

hibernate中inverse属性详解

术语"inverse"直译为"反转".在Hibernate中,inverse属性指定了关联关系中的方向.关联关系中,inverse="false"的为主动方,由主动方维护关联关系.在一对多关联中,将one方的inverse设置为true,这将有助于性能的改善.也就是让所有新生主动来报到.Hibernate: insert into district (name, id) values (?, ?)Hibernate: insert into st

hibernate中inverse属性

inverse属性:是在维护关联关系的时候起作用的. 表示控制权是否转移(在一的一方起作用) inverse=false    不反转,当前方有控制权 inverse=true  控制反转,当前方没有控制权 保存数据:会影响到多的一方的数据 一的一方在保存数据时候 不会维护多的一方数据(多的一方数据不会保存到数据库中) 解除关联关系.clear()  方法 inverse=false  解除与多的一方关系  就是把多的一方的外键设为null inverse=true   不会解除 删除关联关系

hibernate中SessionFactory,Session的理解?

Session接口         Session接口对于Hibernate   开发人员来说是一个最重要的接口.然而在Hibernate中,实例化的Session是一个轻量级的类,创建和销毁它都不会占用很多资源.这在实际项目 中确实很重要,因为在客户程序中,可能会不断地创建以及销毁Session对象,如果Session的开销太大,会给系统带来不良影响.但值得注意的是 Session对象是非线程安全的,因此在你的设计中,最好是一个线程只创建一个Session对象.         在Hibern

Hibernate中的一些关键字理解

ORM的理解: ORM(Object/Relation Mapping): 对象/关系映射ORM 主要解决对象-关系的映射: ORM的思想:将关系数据库中表中的记录映射成为对象,以对象的形式展现,程序员可以把对数据库的操作转化为对对象的操作.ORM 采用元数据来描述对象-关系映射细节, 元数据通常采用 XML 格式, 并且存放在专门的对象-关系映射文件中.元数据:描述数据的数据, Object.hbm.xml文件: Hibernate 将根据这个映射文件来生成各种 SQL 语句 映射文件的扩展名

【Hibernate】详解Hibernate中的inverse=”true”

首先两个类,一个是班级类,一个是学生类: public class Grade{ private int id; private String name; private Set students = new HashSet(); } public class Student { private int id; private String studentName; } 数据库中表的结构: t_grade: 两个字段:id  name t_student: 三个字段:id  studentNam