【Hibernate】详解Hibernate中的inverse=”true”
来源:互联网 发布:地理信息系统算法试卷 编辑:程序博客网 时间:2024/06/14 15:12
首先两个类,一个是班级类,一个是学生类:
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 studentName gradeid
Grade类的映射文件:Grade.hbm.xml(此时是单向关联)
<hibernate-mapping><class name="Grade" table="t_grade" lazy="false"> <id name="id"> <generator class="native"/></id> <property name="name"/> <strong><set name="students" cascade="save-update" lazy="false"> <key column=" gradeid "/> <one-to-many class="Student"/></set></strong></class> </hibernate-mapping>
现在执行以下java代码:
Set students = new HashSet(); Student s1 = new Student ();s1.setStudentName("s1"); Student o2 = new Student();s2.setStudentName ("s2"); students.add(s1);students.add(s2); Grade g = new Grade();g.setName("g1");g1.setStudents(students); session.save(c);
此时Hibernate发出的sql语句如下:
Hibernate: insert into t_grade (name) values (?)Hibernate: insert into t_student (studentName) values (?)Hibernate: insert into t_student (studentName) values (?)Hibernate: update t_student set gradeid=? where id=?Hibernate: update t_student set gradeid =? where id=?
此时查询数据库,显示如下:
t_grade:
id | name
1 g1
t_student:
id | studentName | gradeid
1 s1 1
2 s2 2
在保存Grade对象时,会先发出insert into t_grade(name) values (?)语句将g1同步到数据库中,因为在<set>映射中设置了cascade=”save-update”,所以会同时保存s1、s2两个对象。如果在映射文件中没有设置cascade=”save-update”的话,那么Hibernate就不会自动保存students集合对象,那在更新时将抛出异常:
Hibernate: insert into t_grade (name) values (?)Hibernate: update t_student set gradeid=? where id=?org.hibernate.TransientObjectException: Student
异常分析:
因为在<set>的inverse属性中默认是“inverse=false”,就是由Grade对象当主控方,由它负责关联关系的维护,也就是负责更新t_student表中的gradeid,但是因为没有设置casade=”save-update”,所以students集合中的对象不会在保存grade时自动保存,所以会抛出异常。
<set name="students" cascade="save-update" inverse="true" lazy="false"><key column="gradeid"/><one-to-many class="Student "/></set>
同样执行上述java代码,hibernate发出的语句如下:
Hibernate: insert into t_grade (name) values (?)Hibernate: insert into t_student (studentName) values (?)Hibernate: insert into t_student (studentName) values (?)
此时查看数据库,显示如下:
t_grade:
id | name
1 g1
t_student:
id | studentName | gradeid
1 s1 NULL
2 s2 NULL
这时t_student表的gradeid为NULL,因为设置了inverse=”true”,所以此时Student是主控方,关联关系的维护由Student来完成,在保存Grade对象时,grade不会再维护Students的gradeid属性,必须由student自己来维护,也就是说必须要设置student.setGrade(grade);
当通过Student来维护关联关系时,那么这个关联关系就转换成了双向关联。
在Student类中添加一行代码,变成如下:
public class Student { private int id; private String studentName;private Grade grade;}
此时Student.hbm.xml也要增加几行代码:
<hibernate-mapping><class name="Student" table="t_student"> <id name="id"> <generator class="native"/></id> <property name="studentName"/> <many-to-one name="grade" column="gradeid"/></class> </hibernate-mapping>
此时如果再执行之前的java代码,hibernate发出如下语句:
Hibernate: insert into t_grade (name) values (?)Hibernate: insert into t_student (studentName,gradeid) values (?, ?)Hibernate: insert into t_student (studentName,gradeid) values (?, ?)
此时保存Student对象会为gradeid赋值,因为Student对象中拥有Grade属性,对应gradeid字段,此时查看数据库,还是和之前的一样:
t_grade:
id | name
1 g1
t_student:
id | studentName | gradeid
1 s1 NULL
2 s2 NULL
Gradeid的值还是为NULL的原因是因为上面的java代码中没有设置Student对象的Grade属性,由于我们设置了inverse=”true”,就变为由Student对象维护关联关系,所以必须在java代码中加多一行student.setGrade(grade);
修改代码为:
Grade g = new Grade();Set students = new HashSet(); Student s1 = new Student ();s1.setStudentName("s1"); s1.setGrade(g);Student o2 = new Student();s2.setStudentName ("s2");s2.setGrade(g); students.add(s1);students.add(s2); g.setName("g1");g1.setStudents(students); session.save(c);
此时,hibernate发出如下语句:
Hibernate: insert into t_grade (name) values (?)Hibernate: insert into t_student (studentName,gradeid) values (?, ?)Hibernate: insert into t_student (studentName,gradeid) values (?, ?)
此时再查看数据库:
t_grade:
id | name
1 g1
t_student:
id | studentName | gradeid
1 s1 1
2 s2 1
已经设置了gradeid的值。
总结:在一对多的关联中,在一的一方设置inverse=”true”让多的一方来维护关联关系更有助于优化,因为可以减少执行update语句。
Author:顾故
Sign:别输给曾经的自己
- 【Hibernate】详解Hibernate中的inverse=”true”
- hibernate inverse="true"
- Hibernate中inverse="true"
- hibernate inverse 作用 inverse="true" 作用
- Hibernate inverse 作用 inverse="true" 作用
- Hibernate中的inverse详解
- 关于Hibernate中inverse=true
- hibernate中inverse=true粗解
- 关于Hibernate中inverse=true
- Hibernate中“inverse=true”的理解
- hibernate中inverse=true粗解
- Hibernate中inverse="true"的理解
- Hibernate中inverse="true"的理解
- hibernate中inverse=true的使用
- Hibernate中inverse="true"的理解
- hibernate,inverse="true"的问题
- Hibernate中inverse="true"的理解
- Hibernate中inverse="true"的理解
- C#中调用c++的dll如何适应32位跟64位的平台
- 网络编程socket之listen函数
- 查看oracle的process和session设置的最大值和峰值
- Robot: Duplicate Keywords in Library and Resource Keywords
- python入门笔记-文本读写
- 【Hibernate】详解Hibernate中的inverse=”true”
- Robot: Include and Exclude Tags
- May Challenge 2015(CodeChef 2015年5月月赛)
- FreeType 学习笔记
- filetimetosystemtime函数将filetime转化systemtime后所得的时间依旧是一种UTC时间
- eclipse修改web项目部署路径
- Robot: Set Log Level
- Sicily 14513. Aaah!
- Android添加快捷方式(ShortCut)到手机桌面