文章出處

Session的saveOrUpdate方法是由Hibernate來判斷被操作對象究竟是一個持久化對象還是臨時自由狀態對象。這需要在對象映射文件的主鍵id中定義unsaved-value屬性,如果不顯式定義,則默認為unsaved-value=null。 

unsaved-value可以是下列幾個選項: 
1)null:主鍵是對象類型,Hibernate判斷操作對象的主鍵是否為null,來判斷操作對象是否以被持久化,如果是,調用save方法,生成insert語句,在數據庫中增加一條記錄,如果不是,設置主鍵則直接生成update的SQL語句,發送update,如果數據庫中沒有那條記錄則拋出異常。 
2)none:由于不論主鍵屬性為任何值,都不可能為none,因此Hibernate總是對被操作對象發送update。 
3)any:由于不論主鍵屬性為任何值,都肯定為any,因此Hibernate總是對被操作對象發送save,Hibernate生成主鍵。 

顯式的使用session.save()或者session.update操作一個對象時,實際上市用不到unsaved-value的。 

在一個session中,持久化對象的變化,不需要調用update等顯式語句,由flush方法就可以實現數據庫表的更新。 

不同session之間的對象,也就是游離狀態的對象,必須使用update顯式更新數據庫表。 

修改一個對象,最好的方法是使用session的load方法進行持久化,然后使用set方法實現屬性的修改,一般情況下,不要使用setId方法來修改對象的主鍵值,避免產生意想不到的錯誤。 

使用Hibernate的id generator來生成無業務意義的主鍵,不使用有業務含義的字段作主鍵,不建議使用assigned。 

使用對象類型(String/Integer/Long/...)來做主鍵,而不使用基礎類型(int/long/...)做主鍵

 

01-03-01【Nhibernate (版本3.3.1.4000) 出入江湖】id標簽的unsaved-value屬性

 

父表

復制代碼
  <class name="Model.Customer, Model"
         discriminator-value="0">
    <!--unsaved-value="0" 主鍵表中不需要定義,而是需要在子表中定義-->
    <id name="CustomerId"
        column="CustomerId"
        type="Int32" 
        unsaved-value="0">
      <generator class="native" />
      <!-- unsaved-value used to be null and generator was increment in h2.0.3 -->
    </id>
復制代碼

 

子表

復制代碼
  <class name="Model.Order, Model" 
         table ="[Order]"
         discriminator-value="0" lazy="false">
    <id name="OrderId" 
        column="OrderId" 
        type="Int32" 
        unsaved-value="0">
      <generator class="native" />
      <!-- unsaved-value used to be null and generator was increment in h2.0.3 -->
    </id>
復制代碼

 

了解unsaved-value,需要知道如下知識點:

1.unsaved-value默認值是null
2.id的type標簽屬性可以標示為:
【1】基本對象類型如int,long
【2】對象類型,如Int32,Int64

3.Nhibernate保存機制:
當父對象調用save(),由于級聯的關系,保存子對象,那么保存子對象的方式
到底是Upadate(已經持久化在數據庫中)
還是Save(還沒有持久化在數據庫中,只是剛剛在內存中新new)?

如何判斷是用調用upadte還是調用Save,
答案是:
用unsaved-value的值與HNibernate自動從數據庫中獲取的子類對象的Id進行比較,
   (注意:如果沒有持久化,HNibernate自動從數據庫中獲取的子類對象的Id的值等于null)
  如果是:

【1】unsaved-value的值與子類對象的Id相等,表明沒有持久化,調用save;
  【2】unsaved-value的值與子類對象的Id不相等,表明已持久化,調用Update;


    綜上,
當子表id標簽的type標簽屬性標示為:
【1】基本對象類型如int,long,需要顯示明unsaved-value = 0,因為unsaved-value默認值是null,而基本對象類型如int的默認值為0,
這樣使得即使子類對象還沒有持久化,HNibernate自動從數據庫中獲取的子類對象的Id=0,
這樣根據上述的Nhibernate保存機制,永遠調用Upadte,不會調用save。 
    <id name="OrderId" 
        column="OrderId" 
        type="Int" 
        unsaved-value="0">

【2】對象類型,如Int32,Int64,不需要
    <id name="OrderId" 
        column="OrderId" 
        type="Int32" >

 http://www.cnblogs.com/easy5weikai/p/3746322.html


文章列表


不含病毒。www.avast.com
全站熱搜
創作者介紹
創作者 大師兄 的頭像
大師兄

IT工程師數位筆記本

大師兄 發表在 痞客邦 留言(0) 人氣()