關系數據庫系統本身就比較復雜,加上Hibernate的O/R映射層,復雜度加重了,很容易出現問題,本人將最近遇到的問題和解決方法做一個總結,整理在下面的一系列文章中
正確理解Hibernate的聚合類型(collection)的使用
在Hibernate中正確實現關聯關系中的級聯操作(cascading)
在Hibernate框架中編寫持久對象類實現外鍵關聯的幾點注意事項
本文是第三篇,講解在one-to-many(一對多)關聯關系中的對象類的幾個關鍵方法的實現。主要是equals(),hashCode()和實例化方法。
在在Hibernate中正確實現關聯關系中的級聯操作(cascading)中,我們講了怎樣正確聲明關聯關系和使用持久化方法,我們緊接上一篇的例子,要能夠保證從User到Preference的級聯的正確運行,必須要正確實現equals(),hashCode()和沒有參數的實例化方法。
在equals()和hashCode()的計算中,一定要注意:要使用能夠排他性區別對象的對象屬性成員計算hash code和相等運算。最合適的對象屬性是業務層面的關鍵字(business key或者稱為natural key),而不能使用Hibernate自動計算賦值的primary key(主鍵),當然,以上結論是在一定環境下的,即:我們假設數據庫中的表的主鍵使用某種唯一性id,而不是其natural key。例如,User表中name就是natural key,Hibernate給出了很多理由說明使用natural key作為主鍵的不方便性。
主鍵本來就是唯一的,為什麼不能參與equals()和hashCode()的運算,如果能的話,計算方法大大簡化了:只使用主鍵判斷相等和直接使用主鍵的hash code。實際上,主鍵不是不能這樣用,而是要分場合,如果,主鍵是應用程序賦予的,例如uuid,完全可以使用。但是,如果主鍵是讓Hibernate 在持久化時產生的,就不能使用了,例如,一個對象剛創建,還沒有持久化,就沒有分配一個主鍵,會出現一下異常
java.lang.NullPointerException
以上兩個方法必須實現,否則,在級聯關系中Preference對象的持久化操作將受影響。
如果空實例化操作不實現會怎樣呢?如果Preference的空實例化方法不實現,將出現以下異常
org.hibernate.InstantiationException: No default constructor for entity: xxx