`
lijiejava
  • 浏览: 262360 次
  • 性别: Icon_minigender_1
  • 来自: 南通
社区版块
存档分类
最新评论

Hibernate中inverse="true"的理解

阅读更多
博客已搬至:http://www.muxuanli.com/lmx/

举例如下

Customer类:
public class Customer { 
	private int id; 
	private String name;
private Set orders = new HashSet();
•••
}

即Customer类具有一个set集合属性orders,其中Order是一个普通的类:
public class Order { 
	private int id; 
	private String orderName;
•••
}

数据库中表的结构:
t_customer:  两个字段:id  name
t_order:     三个字段:id  orderName  customerid


Customer类的映射文件:Customer.hbm.xml  (Order类的映射文件忽略)
<hibernate-mapping>
	<class name="test.Customer" table="t_customer" lazy="false">  
		<id name="id"> 
		   <generator class="native"/>
		</id>  
		<property name="name"/>  
		<set name="orders"  cascade="save-update"  lazy="false">
		   <key column="customerid"/>
		   <one-to-many class="test.Order"/>
		</set>
    </class> 
</hibernate-mapping>

执行如下代码:
Set orders = new HashSet(); 
			
Order o1 = new Order();
o1.setOrderName("o1"); 
Order o2 = new Order();
o2.setOrderName("o2");	 
orders.add(o1);
orders.add(o2);  	
			
Customer c = new Customer();
c.setName("aaa");
c.setOrders(orders);  

session.save(c); 

此时Hibernate发出的sql语句如下:
Hibernate: insert into t_customer (name) values (?)
Hibernate: insert into t_order (orderName) values (?)
Hibernate: insert into t_order (orderName) values (?)
Hibernate: update t_order set customerid=? where id=?
Hibernate: update t_order set customerid=? where id=?

查看数据库:
t_customer :                    t_order:   

id   |  name                   id   |   orderName   |   customerid 
1       aaa                    1           o1              1
                               2           o2              1 

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

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

同样执行上述代码,发出如下语句:
Hibernate: insert into t_customer (name) values (?)
Hibernate: insert into t_order (orderName) values (?)
Hibernate: insert into t_order (orderName) values (?)

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

id   |  name                   id   |   orderName   |   customerid 
1       aaa                    1           o1              NULL
                               2           o2              NULL

发现t_order表中customerid的值为NULL,这是由于设置了inverse="true",它意味着
Customer不再作为主控方,而将关联关系的维护工作交给关联对象Orders来完成。在保存Customer时,Customer不在关心Orders的customerid属性,必须由Order自己去维护,即设置order.setCustomer(customer);

如果需要通过Order来维护关联关系,那么这个关联关系转换成双向关联。
修改Order类代码:
public class Order { 
	private int id; 
	private String orderName;  
	private Customer customer;
•••
}

Order.hbm.xml:
<hibernate-mapping>
	<class name="test.Order" table="t_order">  
		<id name="id"> 
		   <generator class="native"/>
		</id>  
		<property name="orderName"/>   
		<many-to-one name="customer" column="customerid"/> 
    </class> 
</hibernate-mapping>

此时数据库中表的结构不会变化。

再次执行上述代码,发出如下sql语句:
Hibernate: insert into t_customer (name) values (?)
Hibernate: insert into t_order (orderName, customerid) values (?, ?)
Hibernate: insert into t_order (orderName, customerid) values (?, ?) 

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

id   |  name                   id   |   orderName   |   customerid 
1       aaa                    1           o1              NULL
                               2           o2              NULL

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

修改上述代码为:
•••
Customer c = new Customer();
			
Set orders = new HashSet(); 
Order o1 = new Order();
o1.setOrderName("o1"); 
o1.setCustomer(c);
Order o2 = new Order();
o2.setOrderName("o2");
o2.setCustomer(c);
orders.add(o1);
orders.add(o2);  	
			
c.setName("aaa");
c.setOrders(orders); 
			
session.save(c); 
••• 
 

执行上述代码,发出如下语句:
Hibernate: insert into t_customer (name) values (?)
Hibernate: insert into t_order (orderName, customerid) values (?, ?)
Hibernate: insert into t_order (orderName, customerid) values (?, ?)

查看数据库:
t_customer :                    t_order:   

id   |  name                   id   |   orderName   |   customerid 
1       aaa                    1           o1              1
                               2           o2              1

发现已经设置了customerid的值。

在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。
分享到:
评论
7 楼 u010214546 2015-05-22  
握着橄榄枝的人 写道
在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。 这句话说错了吧,是在一对多的关联中,在1的一方设置inverse="true",让多的一方来维护关系,我看你也是这么做的啊,你不是在1的一方设置这个inverse="true",然后少了更新语句吗。

我也同意你的说法,我觉得是博主笔误了。
6 楼 握着橄榄枝的人 2014-01-16  
在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。 这句话说错了吧,是在一对多的关联中,在1的一方设置inverse="true",让多的一方来维护关系,我看你也是这么做的啊,你不是在1的一方设置这个inverse="true",然后少了更新语句吗。
5 楼 幕风落雨 2013-08-13  
很全面详细
4 楼 yangyingcan2012 2013-06-19  
讲得比较好,学习了
3 楼 feipigzi 2012-07-19  
w156445045 写道
目前SSH项目中都是这么做的,问下是不是实际的项目中都是这种多对多的关联关系呢?
我用myeclipse的逆向生成的代码也是这种多对多的,
<set name="enterprisePowers" inverse="true" cascade="all">
            <key>
                <column name="eno" precision="18" scale="0" not-null="true" />
            </key>
            <one-to-many class="com.yaxing.pojo.EnterprisePower" />
        </set>
cascade 这个是自己加的~

以上说的是一对多的关系
2 楼 w156445045 2011-12-30  
上面写错了,是双向关系,是不是都建立的这种双向的关系呢?

不是说多对一才是最适合关系数据库的外键的吗?
1 楼 w156445045 2011-12-30  
目前SSH项目中都是这么做的,问下是不是实际的项目中都是这种多对多的关联关系呢?
我用myeclipse的逆向生成的代码也是这种多对多的,
<set name="enterprisePowers" inverse="true" cascade="all">
            <key>
                <column name="eno" precision="18" scale="0" not-null="true" />
            </key>
            <one-to-many class="com.yaxing.pojo.EnterprisePower" />
        </set>
cascade 这个是自己加的~

相关推荐

    inverse=true的总结

    在IT行业中,尤其是在Java开发或者使用ORM框架(如Hibernate)时,“inverse=true”是一个非常重要的概念,它涉及到对象关系映射中的数据管理策略。本文将深入解析“inverse=true”的含义,以及它在实际应用中的作用...

    彻底明白Hibernate中的Inverse

    总结来说,理解并合理运用Hibernate中的`Inverse`属性对于优化数据操作、提高代码可读性和维护性具有重要意义。通过精确控制关联的维护责任,我们可以更好地管理对象关系,实现高效且一致的数据库操作。

    hibernate inverse 个人总结.doc

    在探讨Hibernate的`inverse`属性之前,我们先要理解Hibernate中的对象关系映射(ORM)以及持久化机制。Hibernate是一个流行的Java ORM框架,它允许开发者将数据库操作转换为面向对象的编程模型,使得数据操作更加...

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

    综上所述,理解并正确使用Hibernate中的`inverse`属性对于优化JavaEE应用的数据库操作和提高代码质量具有重要意义。通过深入掌握这一特性,开发者能够更好地管理对象之间的关联,提升应用的性能和稳定性。

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

    在深入探讨Hibernate集合映射中的`inverse`与`cascade`属性之前,我们首先需要理解Hibernate框架的基本概念。Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为Java应用程序提供了一种将对象模型与数据库...

    hibernate inverse和cascade的详细讲解

    - **多对多**:例如,一个`Student`和多个`Course`课程的关系,`inverse`属性通常放在独立的关系表中,并且只能在一方设置为`true`,另一方为`false`,以确保关系的正确维护。 #### 三、Cascade 属性详解 `cascade...

    Hibernate中cascade和inverse应用

    如果在 `Course` 的集合属性(如 `Set&lt;Course&gt;`) 上设置 `inverse="true"`,那么添加或删除 `Course` 时,Hibernate 不会在 `TeacherCourse` 表中插入或删除记录。只有当在 `Teacher` 对象上进行添加或删除操作时,...

    Hibernate中cascade与inverse属性详解

    在我们的例子中,如果在 `Student` 的映射文件中,将 `class` 的关联设置为 `inverse="true"`,那么在保存学生对象时,Hibernate 不会更新班级表中的关联信息,除非在学生对象中显式设置班级。 总结: `cascade` ...

    inverse 例子

    在一对多关系中,如果在多方(ManyToOne)的一端设置了`inverse="true"`,那么Hibernate将不再在多方对象保存或更新时处理关联。相反,它会交给一对一或一对多的那端去处理。这样做可以优化性能,避免不必要的数据库...

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

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

    hibernate 级联(cascade和inverse)一对多

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

    Hibernate级联操作.docx

    在 Hibernate 中,级联操作(Cascade)和反向属性(Inverse)是管理对象关系的重要概念,特别是在处理一对多(One-to-Many)或多对一(Many-to-One)关系时。 **级联操作(Cascade)** 级联操作定义了当主对象被...

    Hibernate 多表映射关系配置

    - 在多对多关系中,你需要确保至少有一个实体负责维护关联,通常是在 `inverse="true"` 的那一方。 - `lazy="true"` 表示该集合默认不会加载,只有在访问时才会加载,以提高性能。 - `cascade` 属性可以控制关联对象...

    Hibernate常见问题

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

    hibernate bag 集合映射

    这里,`propertyName`是Java对象中的集合属性名,`inverse="true"`表示子表的维护由父表负责,`key column`是外键列名,`one-to-many`指定与bag关联的实体类。 2. **注解映射**:如果使用注解,映射将在Java实体类...

    hibernate

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

    hibernate的联合主键怎么设置

    如果 Student 的 `inverse="true"`,那么添加一个新的 Student 时,Hibernate 不会在 TeacherStudent 表中插入新的记录。只有在处理 Teacher 时,Hibernate 才会更新中间表。 - 如果两端都是 `inverse="true"`,则...

Global site tag (gtag.js) - Google Analytics