sparta-紫杉 11/4/21 17:18
讀《Hibernate3.0.2完整中文教程》中的“5.5 實現equals()和hashCode()”一文,在本文中強調,當對于多表關聯的數據進行操作時,尤其想把持久類的實例放入Set時(在Hibernate中這種操作尤其常見),或者想重用脫管實例時,均需要對equals()和hashCode()方法進行重寫。
原因是由于在Hibernate中,需要保證持久化標識(數據庫的行)和僅在特定會話范圍內的Java標識是等值的。我們必然希望Set有明確的語義,以避免混合了來自不同會話中獲取的實例,從而確保數據的持久化不會發生錯誤。
若使用過Set,你會知道Set中是不允許存儲重復值的,這也是為什么Hibernate推薦在多表關聯的映射中采用Set作為存儲實體對象的主要原因。在多表關聯映射中的持久類中,常見如下代碼:
按照Hibernate的提倡,應該在該持久化類里,重寫equals()和hashCode()方法。那么為什么要對這兩個方法進行重寫呢? Set里面不是不允許有重復的值嗎?重寫這兩個方法究竟能起到什么作用?equals()和hashCode()的意義究竟是什么?
這是我看到Hibernate提倡的重寫這兩個方法之后我的疑問!
不妨先來探討一下equals()和hashCode()的作用吧。
實際上,equals()和hashCode()這兩個方法存在的意義是為了區別對象。這兩個方法均來自于Object類。
在對象運行期間,為了在運行期區別各對象,就是通過這兩個方法,它們之間的區別如下:
1.Object類的public boolean equals(Object obj)方法是通過 return this == obj;這種方式比較兩個對象是否相同。這里比較的是引用。2.Object類的public int hashCode()方法,是通過該實例地址轉換為int值。所以不同的Object實例在同一運行期hashCode一定不相同。
現在解決了equals()和hashCode()是什么以及什么作用的問題。
那么再來談談Hibernate的運行機理吧: 在Hibernate的運行期內,通過find或者其他方式提取的對象列表,在不同上下文的操作中,或者在瞬時、持久、脫管三種狀態的變換中,為了避免類名相同,但對象內容不同的實例互相碰撞造成混亂,就需要采用更加準確的區別對象的方法,而此時的equals()和hashCode()已經不能滿足要求,只有對這兩個方法進行重寫,增加對這些持久類的各屬性的內容進行區分,才能真正區分從Hibernate的find方法中提取的對象。
那么什么樣的實例才算是相同的呢? 當然除了你的持久類名標識之外,還需要明確的標識出持久化實例中某些屬性的值也是相等的,兩個實例才算是真正相同。
比如以下兩行數據來自于Person表(字段內容包括ID,姓名name,年齡age,父親姓名fartherName),這是實例相同的例證:
1,王長江,30,王有才;1,王長江,30,王有才;
以下兩行實例是不相同的例證:1,王長江,30,王有才;1,王長江,30,王有財;
哈哈,看出區別來了嗎? 只有一字只差,就會在Hibernate管理的實例中被看作兩個實例,這就是你重寫hashCode()的重要作用。
順便將重寫的hashCode()和equals()也寫在下面吧:
還有,朋友們也可以鍵入以下代碼嘗試一下兩者的區別:
哈哈,朋友們自己總結一下吧!
posted on 2011-05-19 10:40 sparta-紫杉 閱讀(3178) 評論(1) 編輯 收藏 所屬分類: SSH2
Powered by: BlogJava Copyright © sparta-紫杉