石頭JAVA擺地?cái)們?/a>

          JAVA所有的討論-要一點(diǎn)一點(diǎn)的進(jìn)步

            BlogJava :: 首頁(yè) ::  :: 聯(lián)系 ::  :: 管理 ::
            30 隨筆 :: 0 文章 :: 11 評(píng)論 :: 0 Trackbacks

          來(lái)源:thinkGhoster的專欄 - CSDNBlog

            在測(cè)試Hibernate的一對(duì)多雙向關(guān)聯(lián)映射時(shí),碰到很有趣的問(wèn)題,跟inverse屬性直接相關(guān)。

          1、People.hbm.xml

          <hibernate-mapping default-lazy="false">
          <class name="com.persistent.People" table="people">
          <id name="id" column="peopleId" unsaved-value="0">
          <generator class="increment">
          </generator>
          </id>
          <property name="name" column="name"></property>
          <set name="addresses" cascade="save-update">
          <key column="peopleId" not-null="true" />
          <o(jì)ne-to-many class="com.persistent.Address"/>
          </set>
          </class>
          </hibernate-mapping>

          2、Address.hbm.xml

          <hibernate-mapping>
          <class name="com.persistent.Address" table="address">
          <id name="id" column="addressId" unsaved-value="0">
          <generator class="increment">
          </generator>
          </id>
          <many-to-one name="people" column="peopleId" insert="false" update="false"></many-to-one>
          <property name="addressName" column="addressName"></property>
          <property name="codeNumber" column="codeNumber"></property>
          </class>
          </hibernate-mapping>
          3、People.java和Address.java

          public class People ...{
          private long id;
          private String name;
          private Set addresses = new HashSet();
          ...
          }

          public class Address ...{
          private long id;
          private People people;
          private String addressName;
          private String codeNumber;
          ...
          }

          4、數(shù)據(jù)庫(kù)結(jié)構(gòu)

          people表:{peopleId,name}

          address表:{addressId,peopleId,addressName,codeNumber}

          5、測(cè)試代碼

          People people = new People();
          people.setName("linda");
          Address address = new Address();
          address.setAddressName("yunnan");
          address.setCodeNumber("564123");
          address.setPeople(people);
          people.getAddresses().add(address);
          Session session = HibernateSessionFactory.getSession();
          session.beginTransaction();
          session.save(people);
          session.getTransaction().commit();

          6、運(yùn)行結(jié)果

            上面測(cè)試代碼運(yùn)行起來(lái)正確:

          Hibernate: select max(peopleId) from people
          Hibernate: select max(addressId) from address
          Hibernate: insert into people (name, peopleId) values (?, ?)
          Hibernate: insert into address (addressName, codeNumber, peopleId, addressId) values (?, ?, ?, ?)
          Hibernate: update address set peopleId=? where addressId=?

            如果將People.hbm.xml映射改寫一下:

          <set name="addresses" cascade="save-update" inverse="true">
          <key column="peopleId" not-null="true" />
          <o(jì)ne-to-many class="com.persistent.Address"/>
          </set>

            不同之處在于添加了inverse="true",結(jié)果:

          Hibernate: select max(peopleId) from people
          Hibernate: select max(addressId) from address
          Hibernate: insert into people (name, peopleId) values (?, ?)
          Hibernate: insert into address (addressName, codeNumber, addressId) values (?, ?, ?)

            可以看到,peopleId并沒(méi)有寫入到關(guān)聯(lián)的address當(dāng)中,數(shù)據(jù)庫(kù)address表中相應(yīng)記錄的peopleId字段為空。

          7、分析

            在Hibernate中,術(shù)語(yǔ)inverse是反轉(zhuǎn)的意思,在關(guān)聯(lián)關(guān)系中,inverse="false"為主控方,由主控方負(fù)責(zé)維護(hù)對(duì)象的關(guān)聯(lián)關(guān)系。所以上面的映射文件改動(dòng)之后,address為主控方,people為被控方,但是測(cè)試代碼只進(jìn)行了一個(gè)保存操作session.save(people),這是針對(duì)people的,因此無(wú)法正確級(jí)聯(lián)保存address。而原來(lái)的映射文件中(雖然沒(méi)有明確指明,Hibernate默認(rèn)inverse="false"),people為主控方,因此保存people時(shí)它會(huì)保證關(guān)聯(lián)的address的正確保存。

            也就是說(shuō),Hibernate僅僅按照主控方對(duì)象的狀態(tài)的變化來(lái)同步更新數(shù)據(jù)庫(kù)。按照原來(lái)的映射文件,people.getAddresses().add(address),即主控方對(duì)象的狀態(tài)發(fā)生了改變,因此數(shù)據(jù)庫(kù)會(huì)跟著對(duì)象狀態(tài)的變化來(lái)同步更新數(shù)據(jù)庫(kù);而address.setPeople(people),即被控方對(duì)象的狀態(tài)發(fā)生了改變,它是不能觸發(fā)對(duì)象和數(shù)據(jù)庫(kù)的同步更新的。


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 托里县| 长汀县| 白城市| 吉首市| 赞皇县| 乐昌市| 子长县| 同江市| 永善县| 金昌市| 呼伦贝尔市| 泰宁县| 安达市| 衡水市| 文水县| 循化| 东丰县| 阿拉善左旗| 九台市| 太谷县| 峨边| 隆子县| 开阳县| 淮南市| 平泉县| 叙永县| 五大连池市| 临夏县| 自治县| 海城市| 南溪县| 阳原县| 玉山县| 文化| 额尔古纳市| 涪陵区| 黄平县| 宜兰市| 肇州县| 永春县| 集安市|