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" >
文章列表