inverse属性

2014/04/17 16:28
对于Hibernte中hbm.xml文件中的<Set>标签中的inverse属性,一直以来都理解的很模糊。最后终于花了一个上午的时间专门去写代码测试这个属性的作用,最后总算是有了自己清晰的认识。
我的理解:
设定两个类:Classes(班级类)、Student(学生类),关系为一对多:一个班级有多个学生,一个学生只有一个班级
Classes中有studentSet集合,表示多个学生集合
Student中有Classes对象,表示一个班级

Classes.hbm.xml(班级)中Set元素
<set name="studentSet" cascade="save-update" inverse="false" lazy="true">
   <key column="CLASS_ID"/>
   <one-to-many class="Student"/>
</set>

Student.hbm.xml(学生)
<many-to-one name="classes" column="CLASS_ID" class="Classes" cascade="save-update"/>

inverse是用来控制 对象关系的维护方,即维护外键值。(之前一直理解成维护所有信息,悲剧啊。)
在Classes.hbm.xml中inverse设为false,这也是默认的选项。
设置为false,表示两端都会去维护对象之间的关系,即Classes端和Student端都会去维护。
如下代码:

Classes classes = (Classes)session.get(Classes.class, 1L);
Student stu = (Student)session.get(Student.class, 2L);
classes.getStudentSet().add(stu);//向OID为1的班级中添加OID为2的学生对象
stu.setClasses(classes);//向OID为2的学生对象设置其班级
session.save(classes);

结果是Hibernate 执行两次下面语句
update STUDENT  set CLASS_ID=1  where ROW_ID=2 
原因是当执行到
classes.getStudentSet().add(stu);
Classes端发现自己被添加了一个学生,而它又是维护端,所以Classes端会发出一次更新的SQL。
当执行到
stu.setClasses(classes);
Student端发现自己被设置了一个班级,而它也是维护端,所以Student端也会发出一次更新的SQL。
这就是如果不使用inverse的话会造成的问题,即重复更新。

下面看下inverse设置为true的时候

Classes.hbm.xml(班级)中Set元素
<set name="studentSet" cascade="save-update" inverse="true" lazy="true">
   <key column="CLASS_ID"/>
   <one-to-many class="Student"/>
</set>

Student.hbm.xml(学生)
<many-to-one name="classes" column="CLASS_ID" class="Classes" cascade="save-update"/>

inverse设置为true:表示两个操作
1.Classes类放弃维护关系的控制。
2.让Student类来维护关系。
代码:
Classes classes = (Classes)session.get(Classes.class, 1L);
Student stu = (Student)session.get(Student.class, 2L);
classes.getStudentSet().add(stu);
session.save(classes);
这次执行,与上例的结果不一样,Hibernate并没有执行更新Student表中的CLASS_ID的语句
原因就是因为session保存的是classes类,而Classes端已经放弃了维护,所以Hibernate不会去执行更新语句。
代码:
Classes classes = (Classes)session.get(Classes.class, 1L);
Student stu = (Student)session.get(Student.class, 2L);
stu.setClasses(classes)
session.save(stu);
这次执行Hibernate就发出了更新语句,因为Student更新了与Classes的关系,并且Student端是维护端,所以会更新。
综上所述,可以得出以下结论
如果inverse设置为false的话,优点是无论保存哪端的对象,hibernate都会进行更新,随之带来的缺点是可能会执行重复的更新语句。
如果inverse设置为true的话,优点是避免了重复更新,随之带来的缺点是,只有保存的是维护端的对象时,才会进行更新
一般实际开发来说,都会设置为true,这样可以避免重复更新,而且实际开发中,一般也常保存多的一方的对象,即维护端。

特殊情况:如果是多对多的关系,例如Teacher和Student,一个老师会有多个学生,一个学生也会有多个老师。
这时候如果是双向关联,即Teacher中有Student的集合, Student中有Teacher的集合
这时候,一般只将一端的inverse设置为true,另一端设置为false
如果两端都设置为true,则Hiberante就不会去维护其关系了。
原因是,当保存Teacher对象时,Hiberate会认为是Student端是维护端,而不会发出更新关系的语句。
而保存的是Student对象时,Hibernate又会认为Teacher是维护端,也不会发现更新关系的语句。







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值