﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-chou's blog-随笔分类-about ssh</title><link>http://www.blogjava.net/chou/category/32794.html</link><description>records of my java learning process </description><language>zh-cn</language><lastBuildDate>Sun, 07 Sep 2008 13:57:15 GMT</lastBuildDate><pubDate>Sun, 07 Sep 2008 13:57:15 GMT</pubDate><ttl>60</ttl><item><title>Hibernate一对多双向关联及inverse的作用(转)</title><link>http://www.blogjava.net/chou/archive/2008/09/06/227398.html</link><dc:creator>chou</dc:creator><author>chou</author><pubDate>Sat, 06 Sep 2008 06:41:00 GMT</pubDate><guid>http://www.blogjava.net/chou/archive/2008/09/06/227398.html</guid><wfw:comment>http://www.blogjava.net/chou/comments/227398.html</wfw:comment><comments>http://www.blogjava.net/chou/archive/2008/09/06/227398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chou/comments/commentRss/227398.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chou/services/trackbacks/227398.html</trackback:ping><description><![CDATA[<span class="Apple-style-span" style="word-spacing: 0px; font: 12px/20px Arial; text-transform: none; color: rgb(51,51,51); text-indent: 0px; white-space: normal; letter-spacing: normal; border-collapse: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 2px; webkit-border-vertical-spacing: 2px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0">在测试Hibernate的一对多双向关联映射时，碰到很有趣的问题，跟inverse属性直接相关。<br style="line-height: normal" />
<br style="line-height: normal" />
1、People.hbm.xml<br style="line-height: normal" />
<br style="line-height: normal" />
＜hibernate-mapping default-lazy="false"＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜class name="com.persistent.People" table="people"＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜id name="id" column="peopleId" unsaved-value="0"＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜generator class="increment"＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜/generator＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜/id＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜property name="name" column="name"＞＜/property＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜set name="addresses" cascade="save-update"＞<br style="line-height: normal" />
＜key column="peopleId" not-null="true" /＞<br style="line-height: normal" />
＜one-to-many class="com.persistent.Address"/＞<br style="line-height: normal" />
＜/set＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜/class＞<br style="line-height: normal" />
＜/hibernate-mapping＞<br style="line-height: normal" />
<br style="line-height: normal" />
2、Address.hbm.xml<br style="line-height: normal" />
<br style="line-height: normal" />
＜hibernate-mapping＞<br style="line-height: normal" />
＜class name="com.persistent.Address" table="address"＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜id name="id" column="addressId" unsaved-value="0"＞<br style="line-height: normal" />
＜generator class="increment"＞<br style="line-height: normal" />
＜/generator＞<br style="line-height: normal" />
＜/id＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜many-to-one name="people" column="peopleId" insert="false" update="false"＞＜/many-to-one＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜property name="addressName" column="addressName"＞＜/property＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜property name="codeNumber" column="codeNumber"＞＜/property＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜/class＞<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
＜/hibernate-mapping＞<br style="line-height: normal" />
3、People.java和Address.java<br style="line-height: normal" />
<br style="line-height: normal" />
public class People ...{<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
private long id;<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
private String name;<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
private Set addresses = new HashSet();<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
...<br style="line-height: normal" />
}<br style="line-height: normal" />
<br style="line-height: normal" />
public class Address ...{<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
private long id;<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
private People people;<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
private String addressName;<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
private String codeNumber;<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
...<br style="line-height: normal" />
}<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
<br style="line-height: normal" />
4、数据库结构<br style="line-height: normal" />
<br style="line-height: normal" />
people表：{peopleId,name}<br style="line-height: normal" />
<br style="line-height: normal" />
address表：{addressId,peopleId,addressName,codeNumber}<br style="line-height: normal" />
<br style="line-height: normal" />
5、测试代码<br style="line-height: normal" />
<br style="line-height: normal" />
People people = new People();<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
people.setName("linda");<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
Address address = new Address();<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
address.setAddressName("yunnan");<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
address.setCodeNumber("564123");<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
address.setPeople(people);<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
people.getAddresses().add(address);<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
Session session = HibernateSessionFactory.getSession();<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
session.beginTransaction();<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
session.save(people);<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
session.getTransaction().commit();<span class="Apple-converted-space">&nbsp;</span><br style="line-height: normal" />
<br style="line-height: normal" />
6、运行结果<br style="line-height: normal" />
<br style="line-height: normal" />
　　上面测试代码运行起来正确：<br style="line-height: normal" />
<br style="line-height: normal" />
Hibernate: select max(peopleId) from people<br style="line-height: normal" />
Hibernate: select max(addressId) from address<br style="line-height: normal" />
Hibernate: insert into people (name, peopleId) values (?, ?)<br style="line-height: normal" />
Hibernate: insert into address (addressName, codeNumber, peopleId, addressId) values (?, ?, ?, ?)<br style="line-height: normal" />
Hibernate: update address set peopleId=? where addressId=?<br style="line-height: normal" />
<br style="line-height: normal" />
　　如果将People.hbm.xml映射改写一下：<br style="line-height: normal" />
<br style="line-height: normal" />
＜set name="addresses" cascade="save-update" inverse="true"＞<br style="line-height: normal" />
＜key column="peopleId" not-null="true" /＞<br style="line-height: normal" />
＜one-to-many class="com.persistent.Address"/＞<br style="line-height: normal" />
＜/set＞<br style="line-height: normal" />
<br style="line-height: normal" />
　　不同之处在于添加了inverse="true"，结果：<br style="line-height: normal" />
<br style="line-height: normal" />
Hibernate: select max(peopleId) from people<br style="line-height: normal" />
Hibernate: select max(addressId) from address<br style="line-height: normal" />
Hibernate: insert into people (name, peopleId) values (?, ?)<br style="line-height: normal" />
Hibernate: insert into address (addressName, codeNumber, addressId) values (?, ?, ?)<br style="line-height: normal" />
<br style="line-height: normal" />
　　可以看到，peopleId并没有写入到关联的address当中，数据库address表中相应记录的peopleId字段为空。<br style="line-height: normal" />
<br style="line-height: normal" />
7、分析<br style="line-height: normal" />
<br style="line-height: normal" />
　　在Hibernate中，术语inverse是反转的意思，在关联关系中，inverse="false"为主控方，由主控方负责维护对象的关联关系。所以上面的映射文件改动之后，address为主控方，people为被控方，但是测试代码只进行了一个保存操作session.save(people)，这是针对people的，因此无法正确级联保存address。而原来的映射文件中（虽然没有明确指明，Hibernate默认inverse="false"），people为主控方，因此保存people时它会保证关联的address的正确保存。<br style="line-height: normal" />
<br style="line-height: normal" />
　　也就是说，Hibernate仅仅按照主控方对象的状态的变化来同步更新数据库。按照原来的映射文件，people.getAddresses().add(address)，即主控方对象的状态发生了改变，因此数据库会跟着对象状态的变化来同步更新数据库；而address.setPeople(people)，即被控方对象的状态发生了改变，它是不能触发对象和数据库的同步更新的。</span>
<img src ="http://www.blogjava.net/chou/aggbug/227398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chou/" target="_blank">chou</a> 2008-09-06 14:41 <a href="http://www.blogjava.net/chou/archive/2008/09/06/227398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>