Inverse is the basic concept in hibernate bidirectional relationship

The role of inverse in hibernate

zpeng421x  |  Browsing 50722 times
Recommended on 2016-06-01 21:43:19 Best answer
  Inverse is the basic concept in hibernate bidirectional relationship. The real role of inverse is to specify which party maintains the relationship between them . When a party specifies "inverse=false" (default), then that party is responsible for the relationship between them . 
  Hibernate updates the database synchronously only according to changes in the state of the master object. According to the original mapping file, people.getAddresses().add(address), that is, the state of the master object has changed, so the database will update the database synchronously with the change of the object state; and address.setPeople(people), that is When the state of the object being charged has changed, it cannot trigger the synchronous update of the object and the database.
  Take the simplest one-to-many parent-child relationship. Then the code is written as:
  relationship mapping in parent
{set name="children" lazy="true" inverse="true"}
{key column="parent_id"/}
{one-to-many class="test.Child" /}
{/set}
  Relation Mapping in Son
{many-to-one name="parent" column="parent_id" not-null="true"/}

Parent p = new Parent();
Child c = new Child() ;
c.setParent(p);

  session.save(p);
session.flush();
  Note: {many-to-one} is always set to "inverse=false", and this property does not exist in Mapping!
  The result of this operation is:
  Hibernate: insert into parent (id) values ​​(?)
Hibernate: insert into child (parent_id, id) values ​​(?, ?)
  Then if c.setParent(p) is commented out, the result is:
  Hibernate: insert into parent (id) values ​​(?)

you can call me cousin  | Electronic product technical support

Specialties: Computer

other answers

inverse常用于一对多双向关联关系中。
以Student(学生)和Class(班级)为例,它们之间的关系为一对多的关系,即一个学生只能属于一个班级,一个班级可以包含多个学

生。
学生类定义代码:
Class Student{
private int id;
private String name;
private Class class;
//省略getter()和setter()方法
}
班级类定义代码:
Class Class{
private int id;
private String name;
private Set students = new HashSet();
//省略getter()和setter()方法
}
Student类的映射文件:
<class name="Student" table="STUDENT">
<id name="id" type="int" column="ID">
<generator class="native" />
</id>
<property name="name" type="string" column="NAME" />
<many-to-one name="class" column="CLASS_ID" class="Class" cascade="save-update" />
</class>
Class类的映射文件:
<class name="Class" table="CLASS">
<id name="id" type="int" column="ID">
<generator class="native" />
</id>
<property name="name" type="string" column="NAME" />
<set name="students" table="STUDENT" cascade="save-update" inverse="false">
<key column="CLASS_ID" />
<one-to-many class="Student" />
</set>
</class>
希望你能对这两个映射文件所表达的数据库模式有正确的认识。即STUDENT表中存在一个名为CLASS_ID的字段,它和CLASS表中的ID字段是主外键关系。那个inverse属性就是用来规定是由谁(Student或Class)来维护这个主外键关系的。
inverse的默认值为false。
在处理逻辑代码中,如下:
Class c1 = new Class();
c1.setName("一班");
Student s1 = new Student();
Student s2 = new Student();
s1.setName("Jason");
s2.setName("Tom");
c1.getStudents().add(s1);
c2.getStudents().add(s2);
s1.setClass(c1);
s2.setClass(c1); //注释1
session.save(c1);
上面的代码会使Hibernate执行五条SQL语句,其中前三条是insert插入语句,后两条是update更新语句。插入就不用说了,那么为什么还要有更新语句呢?这是因为Class类映射文件的<set>元素中指定了inverse="false",这就告之Hibernate:STUDENT表与CLASS表的主外键关系是由Class类来维护的。当执行save后,执行了三条insert语句,这三条语句中的后两条是插入到STUDENT表的,它们的CLASS_ID字段是通过s1.getClass().getID()取出的,假如我将上面“注释1”处修改为s2.setClass(c2);(c2是另一个Class对象,可能是持久化对象),这样,主外键关系不就乱了吗。为了保证主外键关系,Hibernate在这种情况下会再执行两条update语句来更改STUDENT表中两个新插入记录的CLASS_ID字段,当然,这时CLASS_ID字段的取值是从c1对象中直接取得,而不再是s1.getClass().getID()方式了。
如果我们将Class类映射文件的<set>元素中的inverse属性修改为true,这就是告诉Hibernate:Class类不维护主外键关系了,这个任务就交给了Student类。于是,我们再执行上面的代码,Hibernate就会只执行三条insert语句,而不会执行任何update语句。因为Hibernate会通过Student类的s1.getClass().getID()和s2.getClass().getID()来确定CLASS_ID字段的值。
故,为了节省数据库资源,省却不必要的update语句,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true,即将主外键的关系交由多方来维护。
打个比方:在一个公司中,是老板认识所有的员工容易,还是所有员工认识老板容易?
我是一个Hibernate的初学者,前两天刚刚研究了一下inverse属性,有所心得。写了这么多东西,希望能对你有所帮助。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325868048&siteId=291194637