石頭JAVA擺地攤兒

          JAVA所有的討論-要一點一點的進步

            BlogJava :: 首頁 ::  :: 聯系 ::  :: 管理 ::
            30 隨筆 :: 0 文章 :: 11 評論 :: 0 Trackbacks

          來源:thinkGhoster的專欄 - CSDNBlog

            在測試Hibernate的一對多雙向關聯映射時,碰到很有趣的問題,跟inverse屬性直接相關。

          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" />
          <one-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、數據庫結構

          people表:{peopleId,name}

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

          5、測試代碼

          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、運行結果

            上面測試代碼運行起來正確:

          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" />
          <one-to-many class="com.persistent.Address"/>
          </set>

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

          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并沒有寫入到關聯的address當中,數據庫address表中相應記錄的peopleId字段為空。

          7、分析

            在Hibernate中,術語inverse是反轉的意思,在關聯關系中,inverse="false"為主控方,由主控方負責維護對象的關聯關系。所以上面的映射文件改動之后,address為主控方,people為被控方,但是測試代碼只進行了一個保存操作session.save(people),這是針對people的,因此無法正確級聯保存address。而原來的映射文件中(雖然沒有明確指明,Hibernate默認inverse="false"),people為主控方,因此保存people時它會保證關聯的address的正確保存。

            也就是說,Hibernate僅僅按照主控方對象的狀態的變化來同步更新數據庫。按照原來的映射文件,people.getAddresses().add(address),即主控方對象的狀態發生了改變,因此數據庫會跟著對象狀態的變化來同步更新數據庫;而address.setPeople(people),即被控方對象的狀態發生了改變,它是不能觸發對象和數據庫的同步更新的。

          posted on 2007-10-24 19:31 石頭JAVA擺地攤兒 閱讀(356) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 喀喇沁旗| 二手房| 临朐县| 含山县| 来安县| 迁西县| 中阳县| 九龙坡区| 吴忠市| 海城市| 安丘市| 大余县| 长泰县| 武宁县| 通化市| 定州市| 军事| 隆安县| 信丰县| 西青区| 玛曲县| 鹿邑县| 汉川市| 迁西县| 饶平县| 平江县| 石景山区| 谢通门县| 衢州市| 武汉市| 香港| 纳雍县| 永清县| 阿拉善右旗| 昭觉县| 深州市| 繁峙县| 云和县| 仪征市| 富阳市| 永丰县|