石頭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)航:
           
          主站蜘蛛池模板: 齐齐哈尔市| 墨江| 高阳县| 成武县| 霍山县| 手机| 泊头市| 永定县| 舞钢市| 城口县| 炉霍县| 临夏市| 洛隆县| 梅州市| 尤溪县| 苏州市| 安泽县| 黄山市| 三河市| 礼泉县| 莲花县| 吐鲁番市| 阜平县| 旬邑县| 姜堰市| 高雄市| 会昌县| 个旧市| 黎川县| 林周县| 斗六市| 曲松县| 临泽县| 珠海市| 本溪| 平南县| 化隆| 揭西县| 石泉县| 神木县| 华宁县|