1. inverse="true"
例如 one-to-many 关系User (1) - Order(*)
Java代码:
public class User {
private Set<Order> orders = new HashSet<Order>();
// ...
}
public class Order {
private User user;
// ..
}
对应的 mapping files:
Order.hbm.xml
<hibernate-mapping package="org.pprun.hjpetstore.domain">
<class name="Order" table="Orders">
...
<!-- owner side of this bidirectional one-to-many association (user to order)-->
<many-to-one column="userId" foreign-key="fk_order_userId" name="user" not-null="true" />
</class>
</hibernate-mapping>
User.hbm.xm
<hibernate-mapping package="org.pprun.hjpetstore.domain">
<class name="User" table="User">
...
<set cascade="all" inverse="true" name="orders">
<key column="userId" not-null="true"/>
<one-to-many class="Order"/>
</set>
</class>
</hibernate-mapping>
好了,以上都是作为开发者必须了解的内容,也是日常工作之一。
inverse 的由来
在 Java 的世界里,我们将利用如下代码建立起 object instance 关系:
user.getOrders().add(newOrder);
order.setUser(user);
这个建立关系的代码一般会反映在 domain 对象中的一个方法中,这个方法有一个恐怖的名字 scaffolding method:
/** scaffolding code for collection field */
public final void addOrder(Order order) {
if (order == null) {
throw new IllegalArgumentException("Can't add a null Order.");
}
order.setUser(this);
this.getOrders().add(order);
}
那么,如果在 User.hbm.xm 对于关系的映射没有指定 inverse="true" 会发生什么?
Hibernate 将发出两条不同的 SQL 做同一件事情,建立起关系,但反映在数据库中(见ERD),只是对同一个字段 orders.userId 这个外键进行操作。
通过指定 inverse="true", 我们告诉 hibernate 哪端是 owner 端,并将维护实体关系。而另一端是 inverse 端,不需要维护关系。
规则1,双向many-to-one 关系,one 端永远是 inverse 端,而many 端永远是 owner 端。
这下明白了 inverse 的含义了,它是相对于实体关系的 owner 来讲的。
Owner 怎么来的?
在这个例子中,User 是 one, Order 是 many, 因 Order 是 owner, 所以在 Orders 表中包含外键关系 userId. 这是 Owner 的来历-- 谁拥有外键字段,谁就是 Owner.
规则2, 双向 one-to-one 关系,决定取决于 ERD,而非 JAVA, 同样是哪个实体拥有外键,哪边就是 Owner, 相反,另一端(other side)就是inverse.
规则3,双向 many-to-many,因为实现这一关系的有效办法是利用独立关联表(join table), 所以我们不得不任意指定任一端为 owner(另外一端就是 inverse),但外键关系(复合外键)实际上是在独立的关联表中。
inverse 该放在哪边?
规则1,双向many-to-one 关系,one 端永远是 inverse 端,而many 端永远是 owner 端。
有这个规则,在映射关系时,one-to-many 是指定 one 端,即 inverse 端,因些应该指定 inverse 属性。
<set cascade="all" inverse="true" name="orders">
<key column="userId" not-null="true"/>
<one-to-many class="Order"/>
</set>
因此,many-to-one 是 owner 端,不应该指定 inverse 属性:
<!-- owner side of this bidirectional one-to-many association (user to order)-->
<many-to-one column="userId" foreign-key="fk_order_userId" name="user" not-null="true" />
因此完整的映射如下(fixed 错误的注释,请好好理解一下注释)
<hibernate-mapping package="org.pprun.hjpetstore.domain">
<class name="Order" table="Orders">
...
<!-- owner side of this bidirectional one-to-many association (user to order)-->
<many-to-one column="userId" foreign-key="fk_order_userId" name="user" not-null="true" />
</class>
</hibernate-mapping>
User.hbm.xm
<hibernate-mapping package="org.pprun.hjpetstore.domain">
<class name="User" table="User">
...
<!--
inverse="true" means Order is the owner side (User is the mirror side - inverse),
Order will take charge of relationship 'userId', which is the foreign-key in Order.
If only call user.getOrders().add(newOrder), no changes are made persistent.
But only call order.setUser(user) will make the relationship set - means the foreign-key will be persisted.
-->
<set cascade="all" inverse="true" name="orders">
<key column="userId" not-null="true"/>
<one-to-many class="Order"/>
</set>
</class>
</hibernate-mapping>
2. Inverse和Cascade的比较
Inverse:负责控制关系,默认为false,也就是关系的两端都能控制,但这样会造成一些问题,更新的时候会因为两端都控制关系,于是重复更新。一般来说有一端要设为true。
Cascade:负责控制关联对象的级联操作,包括更新、删除等,也就是说对一个对象进行更新、删除时,其它对象也受影响,比如我删除一个对象,那么跟它是多对一关系的对象也全部被删除。
举例说明区别:删除“一”那一端一个对象O的时候,如果“多”的那一端的Inverse设为true,则把“多”的那一端所有与O相关联的对象外键清空;如果“多”的那一端的Cascade设为Delete,则把“多”的那一端所有与O相关联的对象全部删除。
3. 各个配置属性含义
<many-to-one name="parent" class="com.client.model.ClientChildType" update="false" insert="false" cascade="none">
<column name="parent_id"/>
</many-to-one>
update:进行update操作时是否包含此字段
insert:进行insert操作时是否包含此字段
name:映射类属性的名字
column:关联的字段
class:关联类的名字
cascade:设置操作中的级联策略 可选值为 all所有操作情况均进行级联、none所有操作情况均不进行级联、save-update执行save和update操作时级联、delete执行删除操作时级联
fetch:设置抓取数据的策略 默认值为select序列选择抓取 可选值为join外连接抓取
property-ref:指定关联类的一个属性,这个属性将会和本类的外键相对应(当外键参照一键时需要指定改属性)
fetch属性
hibernate抓取策略(单端代理的批量抓取fetch=select(默认)/join)
测试用例:
Student student = (Student)session.get(Student.class, 1);
System.out.println(student.getName());
System.out.println(student.getClasses().getName());
1)保持默认,同fetch="select",如:
<many-to-one name="classes" column="classesid" fetch="select"/>
fetch="select",另外发送一条select语句抓取当前对象关联实体或集合
执行结果:2条语句
Hibernate: select student0_.id as id1_0_, student0_.name as name1_0_, student0_.class_id as class3_1_0_ from student_join student0_ where student0_.id=?
学生1
Hibernate: select classes0_.id as id0_0_, classes0_.name as name0_0_ from classes_join classes0_ where classes0_.id=?
高一(1)班
======================================
2)设置fetch="join",如:
<many-to-one name="classes" column="classesid" fetch="join"/>
fetch="join",hibernate会通过select语句使用外连接来加载其关联实体或集合
此时lazy会失效
执行结果:一条join语句
Hibernate: select student0_.id as id1_1_, student0_.name as name1_1_, student0_.class_id as class3_1_1_, classes1_.id as id0_0_, classes1_.name as name0_0_ from student_join student0_ left outer join classes_join classes1_ on student0_.class_id=classes1_.id where student0_.id=?
学生1
高一(1)班
分享到:
相关推荐
### Hibernate Inverse 和 Cascade 的详细讲解 #### 一、引言 在ORM(Object-Relational Mapping)领域,Hibernate作为一款流行的Java持久层框架,它提供了丰富的API和配置选项来帮助开发者实现对象与数据库表之间...
Hibernate中cascade与inverse属性详解
在 Hibernate 框架中,`cascade` 和 `inverse` 是两个重要的概念,它们主要用于管理对象之间的持久化关系,特别是涉及到一对一(one-to-one)、一对多(one-to-many)和多对多(many-to-many)关系时。这两个属性都...
Hibernate中Inverse和Cascade的区别.html
至于博文链接,虽然没有提供具体内容,但可以推测博主可能详细讲解了在特定工具或框架中如何配置和使用“inverse”和“cascade”,并可能给出了一些示例和最佳实践。 在压缩包文件“inverse_cascade”中,可能包含...
在探讨Hibernate框架中的级联操作(cascade)与控制权反转(inverse)之前,我们需要先对Hibernate有一个基本的理解。Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为Java应用提供了一种将对象模型映射到...
在Java的持久化框架Hibernate中,级联操作(Cascade)和反转(Inverse)是两个重要的概念,它们主要用于管理对象关系模型中的关联关系。在一对多的关系中,这些特性可以帮助简化数据操作,提高代码的可读性和维护性...
在Java世界里,Hibernate是一个非常流行的对象关系映射(ORM)框架,它使得开发者可以使用面向对象的方式来操作数据库。在Hibernate中,`Inverse`是一个重要的概念,它涉及到实体之间的关联管理。本文将深入探讨`...
在探讨Hibernate的`inverse`属性之前,我们先要理解Hibernate中的对象关系映射(ORM)以及持久化机制。Hibernate是一个流行的Java ORM框架,它允许开发者将数据库操作转换为面向对象的编程模型,使得数据操作更加...
在深入探讨Hibernate集合映射中的`inverse`与`cascade`属性之前,我们首先需要理解Hibernate框架的基本概念。Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为Java应用程序提供了一种将对象模型与数据库...
在使用Hibernate时,正确选择和配置cascade选项对于高效地管理和维护实体之间的关系至关重要。通过了解不同选项的特点和应用场景,开发人员可以更加灵活地应对各种业务需求,同时也能够有效地避免潜在的数据一致性...
"NHibernate Inverse & Cascade"是两个关键概念,对于理解和有效使用NHibernate至关重要。 **Inverse属性** Inverse属性主要用于控制NHibernate如何处理关联对象的持久化。在一对多或多对一的关系中,当一个实体...
综上所述,理解并正确使用Hibernate中的`inverse`属性对于优化JavaEE应用的数据库操作和提高代码质量具有重要意义。通过深入掌握这一特性,开发者能够更好地管理对象之间的关联,提升应用的性能和稳定性。
总之,理解并熟练运用Hibernate的关联映射、cascade和inverse是提升Java持久化编程能力的关键步骤。它们可以帮助我们更高效地管理对象与数据库之间的关系,同时降低开发复杂度。通过实践和研究给出的示例,相信你...
总之,理解和正确使用`cascade`和`inverse`属性对于优化Hibernate应用程序的性能和数据一致性至关重要。这两个属性的组合使用可以精确地控制对象关系的生命周期管理,确保数据库中的数据与程序中的对象状态保持一致...
在软件网络技术领域,尤其是在使用Hibernate这种对象关系映射(ORM)框架时,理解和正确使用`cascade`和`inverse`属性至关重要。这两个属性主要用于管理对象之间的关联关系,特别是如何在数据库中维护这些关系。 ...
根据提供的文件信息,我们可以深入探讨Hibernate框架中的几个关键概念,特别是`fetch`, `lazy`, `cascade`, 和 `inverse`关键字的使用与理解。这四个概念在处理对象关系映射(ORM)时非常重要,尤其是在Java环境下...
### Hibernate常用注解详解 #### 一、JPA与Hibernate注解基础 JPA(Java Persistence API)是一种标准规范,用于实现对象关系映射(ORM),允许...理解和熟练掌握这些注解对于使用Hibernate进行持久化操作至关重要。