一、Inverse是hibernate双向关系中的基本概念。inverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之间的关联关系,说白了就是hibernate如何生成Sql来维护关联的记录!
Hibernate仅仅按照主控方对象的状态的变化来同步更新数据库。按照原来的映射文件,people.getAddresses().add(address),即主控方对象的状态发生了改变,因此数据库会跟着对象状态的变化来同步更新数据库;而address.setPeople(people),即被控方对象的状态发生了改变,它是不能触发对象和数据库的同步更新的。
(实例1):
举个最简单的一对多父子关系。那么代码就写成:
父亲中的关系映射
{set name="children" lazy="true" inverse="true"}
{key column="parent_id"/}
{one-to-many class="test.Child"/}
{/set}
儿子中关系映射
{many-to-one name="parent" column="parent_id" not-null="true"/}
Parent p = new Parent();
Child c = new Child();
c.setParent(p); //维护父子之间关系
p.getChildren().add(c);
session.save(p);
session.flush();
注意:{many-to-one}总是设成“inverse=false”的,而且这个属性在Mapping中是不存在的!
这样运行的下来的结果就是:
Hibernate: insert into parent (id) values (?)
Hibernate: insert into child (parent_id, id) values (?, ?)
那么假如c.setParent(p)注释掉,结果就是:
Hibernate: insert into parent (id) values (?)
(实例2):
一个Person可以参加多个Event,一个Event有多个Person参加。
映射文件如下:
<!-- Person.hbm.xml -->
<hibernate-mapping package="events">
<class name="Person" table="person">
<id name="id" column="person_id">
<generator class="native"/>
</id>
<property name="age" length="0"/>
<property name="firstname"/>
<property name="lastname"/>
<set name="events" table="person_event">
<key column="person_id"/>
<many-to-many column="event_id" class="events.Event"/>
</set>
</class>
</hibernate-mapping>
<!-- Event.hbm.xml -->
<hibernate-mapping>
<class name="events.Event" table="events">
<id name="id" column="event_id">
<generator class="native"/>
</id>
<property name="date" column="events_date" type="timestamp"/>
<property name="title" column="events_title"/>
<set name="participants" table="person_event" inverse="true">
<key column="event_id"/>
<many-to-many column="person_id" class="events.Person"/>
</set>
</class>
</hibernate-mapping>
inverse=true的含义: 由双向关联另一方维护该关联,己方不维护该关联(只能进行查询操作)。在上述代码中,由Person方维护该<many-to-many>关系,示例代码如下(以向Person参与的Event中加入新的Event为例):
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
Person p = (Person) session.load(Person.class, personId);
Event e = (Event) session.load(Event.class, eventId);
p.getEvents().add(e);//执行该代码时,hibernate会向中间表 person_event中插入person_id和event_id记录,如果换成e.getParticipants().add(p)的话,该代码将不会被执行,即hibernate不会向表person_event中插入记录。
session.getTransaction().commit();
要注意的一点:在双向关联的关系中,映射的column(和table)的值要一致(即要用相同的表名和列名),不然设置为inverse="true"的这方将失去这个双向关系,而变成了一个单向关联。
二、Inverse和Cascade的比较
Inverse:负责控制关系,默认为false,也就是关系的两端都能控制,但这样会造成一些问题,更新的时候会因为两端都控制关系,于是重复更新。一般来说有一端要设为true。
Cascade:负责控制关联对象的级联操作,包括更新、删除等,也就是说对一个对象进行更新、删除时,其它对象也受影响,比如我删除一个对象,那么跟它是多对一关系的对象也全部被删除。
举例说明区别:删除“一”那一端一个对象O的时候,如果“多”的那一端的Inverse设为true,则把“多”的那一端所有与O相关联的对象外键清空;如果“多”的那一端的Cascade设为Delete,则把“多”的那一端所有与O相关联的对象全部删除。
分享到:
相关推荐
对于`one-to-one`和`many-to-one`关系,它们仅包含单个对象的引用,因此不需要使用`inverse`。 - **Inverse 的值** - **默认值**:`inverse`的默认值为`false`,表示对集合对象的修改会被反映到数据库中。 - **`...
在深入探讨Hibernate集合映射中的`inverse`与`cascade`属性之前,我们首先需要理解Hibernate框架的基本概念。Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为Java应用程序提供了一种将对象模型与数据库...
在探讨Hibernate框架中的级联操作(cascade)与控制权反转(inverse)之前,我们需要先对Hibernate有一个基本的理解。Hibernate是一个开放源代码的对象关系映射(ORM)框架,它为Java应用提供了一种将对象模型映射到...
在Java的持久化框架Hibernate中,级联操作(Cascade)和反转(Inverse)是两个重要的概念,它们主要用于管理对象关系模型中的关联关系。在一对多的关系中,这些特性可以帮助简化数据操作,提高代码的可读性和维护性...
如果我们在ORM工具如Hibernate中定义这种关系,可以设置其中一个关联为“inverse”,表示这个关联的维护责任不在该端。换句话说,更新或删除部门时,相关的员工记录不会被自动更新或删除,反之亦然。这样可以避免...
在关系数据库中,集合类型的数据(如Set、List、Map)不能直接存储,而Hibernate提供了将这些集合类型映射到数据库中的机制,如使用`Set`和`Map`映射关联关系,这使得Java对象的集合属性可以直接与数据库中的记录...
描述提到“使用cascade和inverse优化区和街道关联关系”,这意味着我们将深入理解Hibernate的cascade和inverse属性,以及它们在双向一对多关联关系中的应用。 Hibernate是Java领域中广泛使用的对象关系映射(ORM)...
标题中的“hibernate bag 集合映射”指的是Hibernate框架中的一种关系映射机制。Hibernate是一个流行的Java ORM(对象关系映射)框架,它允许开发者将数据库表与Java类进行映射,使得在处理数据库操作时可以使用面向...
- 相反,如果两边都是 `inverse="false"` 或者默认值,Hibernate 会在每次关联的添加或删除时,都在中间表中进行相应的插入和删除操作,可能会导致重复的插入。 因此,通常我们会根据业务逻辑来合理设置 `inverse`...
本中文帮助文档详细介绍了Hibernate的核心概念、配置、API使用以及最佳实践,是学习和掌握Hibernate不可或缺的参考资料。 1. **Hibernate概述**: - Hibernate是Java世界中最为流行的数据持久化框架之一,由Jboss...
当执行`session.load(User.class, "1")`后,即使调用了`getAddresses()`方法,Hibernate也不会立即查询地址集合,除非显式地遍历集合或访问集合中的某个元素。 ```java User user = (User) session.load(User.class...
在Hibernate的配置文件(hibernate.cfg.xml)中,我们需要指定使用的数据库类型(这里是MySQL)及连接参数: ```xml <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect <property name="...
在本场景中,我们探讨的是如何在Hibernate中配置Many-to-Many映射,并使用MySQL数据库来存储数据。我们将通过映射文件和Domain对象来理解这一过程。 首先,我们需要了解Many-to-Many关系的基本概念。在关系数据库中...
- **多对多(Many-to-Many)**: 使用`<set>`标签配合`inverse="true"`属性或`@ManyToMany`注解。 #### 八、高级特性 - **懒加载(Lazy Loading)**: 只有在真正需要的时候才加载关联对象的数据。 - **批量加载(Batch ...
在Hibernate中,`inverse`属性通常与双向关联的实体一起使用,它决定了哪一方实体在进行删除或更新关联时拥有控制权。例如,在一对多关系中,如果`inverse`属性被设置为`true`,那么这一方将不会主动触发对关联实体...
在Flex中使用Gilead和Hibernate的懒加载,首先需要确保在Hibernate配置文件中对关联实体设置了懒加载属性。例如,如果有一个`User`类和一个`Address`类,`User`中包含一个`List<Address>`,那么在`User`的映射文件中...
以上就是 Hibernate 中的一对多、多对一和多对多关系的配置和使用方法。理解这些关系并正确配置它们是充分利用 Hibernate 框架的关键。在实际项目中,根据业务需求选择合适的关系映射方式,并灵活运用,能够简化...