石頭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僅僅按照主控方對象的狀態(tài)的變化來同步更新數據庫。按照原來的映射文件,people.getAddresses().add(address),即主控方對象的狀態(tài)發(fā)生了改變,因此數據庫會跟著對象狀態(tài)的變化來同步更新數據庫;而address.setPeople(people),即被控方對象的狀態(tài)發(fā)生了改變,它是不能觸發(fā)對象和數據庫的同步更新的。

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

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


          網站導航:
           
          主站蜘蛛池模板: 望都县| 萝北县| 溧水县| 赤壁市| 道真| 富裕县| 梅河口市| 莎车县| 清徐县| 赞皇县| 平谷区| 庆元县| 兴隆县| 墨竹工卡县| 芜湖市| 海原县| 琼海市| 七台河市| 文安县| 镶黄旗| 乐陵市| 股票| 天台县| 金堂县| 渭源县| 太仆寺旗| 新干县| 乐山市| 宣汉县| 佛教| 甘孜| 布尔津县| 哈尔滨市| 龙游县| 上虞市| 盘山县| 阿克| 南岸区| 阿巴嘎旗| 乐都县| 毕节市|