最近遇到一个hibernate使用有趣的问题。一对一级联保存问题。
?
应用的情境是主表,从表。比方说有个主表 比方说班级吧。
?
班级有属性 ?id, name 等等。然后一个从表 就叫student吧,一个班级有多个student.
?
那么配置起来,班级xml 里面如下。
?
?
?
<set name="student" cascade="all" lazy="false" order-by="STUDENTSID desc" > <key column="CLASSID"/> <one-to-many class="com.jj.pojo.student"/> </set>
?
?
这样new 一个班级 class,然后 new 几个学生,放入set,设置class的学生集合 class_one.setStuents(set1);
?
这样hibernate插入class, student,
?
insert into table class (id, $$,$$,...) values(?,?,?..);
?
insert into table student (id, $$,$$,...) values(?,?,?..);
?
update student set $$ =? where **;
?
这样就把 class student都插入表中了,而且也更新了他们之间的关系。
?
现在情境扩展了,每个class又增加了对应的关系,比如说,就叫profile吧,记录每个班级的位置,经费,荣誉值,以及其他的信息,暂且这个表叫做 profile.
?
profileid, classid, attr1, attr2.
?
如果再在class里面用set的话,也可以,但是语义不太贴切,用one-to-one吧,但是这个one-to-one设置开始没设对。就可能只插入,但是没有它们之间的关系。
?
在class里面设置一个
?
? <one-to-one name="profile" class="com.jj.pojo.profile" cascade="all"></one-to-one>
?
同时也在profile里面设置一个。
?
<one-to-one name="class" class="com.jj.pojo.class" ?></one-to-one>?
?
并且改改profile的id.
?
?
? ? ? ? <id name="classid" type="java.lang.Integer" column="CLASSID">
? ? ? ? ? ? <generator class="foreign">
? ? ? ? ? ? ? ? <param name="property">class</param>
? ? ? ? ? ? </generator>
? ? ? ? </id>
?
?
这样设置的话,表面profile表中这个CLASSID这个字段来源于 pofile这个对象中的class对象,插入数据库的时候以此为准。
?
但是有人会问,profile的id不是profileid吧,如果没有设置,怎么可以,事实证明,不设置确实可以,如果mysql中profileid是自增长的,这个值是会有的。
?
但是这个过程和set集合产生的sql语句是不一样的,这个是没有update语句的。
?
我以我的推断来分析一下。
?
hibernate 有缓存,最后入库要以缓存中对象最后的状态为依据,
?
在一对多中,class插入数据库,获得了classid, 同时缓存中的对象的classid由null更新为 一个数字,通知和它相关联的集合更新,相关联的集合如何获知呢,只能通过。
?
<set name="student" cascade="all" lazy="false" order-by="STUDENTSID desc" > <key column="CLASSID"/> <one-to-many class="com.jj.pojo.student"/> </set>
?
和 classid相关联的有集合student.
?
所以hibernate把插入的集合遍历一遍,一次打印出一条update ......
?
但是one-to-one这个设置,
?
我们把class插入的数据库中去的时候,其实这个时刻缓存中的class对象已经获取到了classid,但是和这个class相关联的profile对象是如何去更新状态了,但从one-to-one的配置很难看出哦。
?
<one-to-one name="class" class="com.jj.pojo.class" ></one-to-one>
?
那所以就要配置这个id了,通过这个配置来找他们的关联。
?
<id name="classid" type="java.lang.Integer" column="CLASSID"> <generator class="foreign"> <param name="property">class</param> </generator> </id>?
?所以当插入profile的时候,profile的classid已经是有了的(就是class对象的id),所以直接插入对象即可。
?
所以不需要update了。
?
也许你要说 如果这样的话,set集合的update也可以不需要了,为什么呢? 我其实不知道,感觉这个hibernate的内幕机关重重,水太深。
?
?