討論引發(fā)自這里:
http://www.javaeye.com/topic/8946 以下是我自己的感觸。
equals實(shí)際上是java判斷兩個(gè)對象是否相等的一個(gè)依據;而在set、map這樣的存儲位置與hashcode的集合中, hashcode起著(zhù)計算位置的作用,同時(shí)又要滿(mǎn)足一個(gè)約定:equals相等,則hashcode必然相等。
基于以上,
hibernate實(shí)體的Entity也需要做出如下策略:
1)怎樣才是相等實(shí)體對象
2)在set、map這樣的跟hashcide有關(guān)的集合映射時(shí),如何保證相等對象hashcode也相等。
可以看出關(guān)鍵還是如何決定兩個(gè)實(shí)體對象是否相等,至于hashcode其實(shí)根據equals去實(shí)現的。
許多人提出來(lái)用實(shí)體對象的id來(lái)判斷是否相等,這其實(shí)源于
hibernate的持久對象管理機制。
Hibernate利用id屬性來(lái)管理一類(lèi)持久對象,對于session中的一類(lèi)持久對象,id是唯一的,因此id用作某一類(lèi)持久對象的標識符是合適的。
那么否針對id判斷實(shí)體相等就是合理的策略了嗎?
關(guān)鍵還是看你怎樣才認為實(shí)體對象是相等的,這個(gè)倒不能采取
hibernate對id的特殊用法。
如果認為業(yè)務(wù)屬性無(wú)所謂,只要id相等就相等,那就完全可以用id作為判斷相等的依據。
如果需要根據業(yè)務(wù)屬性來(lái)判定,那么id就不是合理的策略,因為很可能id不等但是業(yè)務(wù)屬性都相等。
如果不是那么關(guān)心重復的實(shí)體對象,因此就不會(huì )覆蓋equals和hashcode方法,直接沿用Object的也是可以的,實(shí)際上很多時(shí)候我們都是這樣做的。
經(jīng)過(guò)仔細的思考,發(fā)現這種提出這種討論本身都是夸大了問(wèn)題。equals和hashcode根本不是
hibernate提出的新概念和新要求。
針對以上的分析,有沒(méi)有最佳實(shí)踐呢?
看看
Hibernate in action,有三種方法:
1. 就是的這種用無(wú)意義主鍵id做hashCode/equals
2. 就是用的所有值做hashCode/equals
3. 用一個(gè)(或者幾個(gè))相對穩定的業(yè)務(wù)字段做hashCode/equals (比如user, 就用userName).
hibernate 推薦的是第3種, 按照這種推薦的做法, 就不會(huì )出現以上說(shuō)的所有問(wèn)題了, 這差不多是最佳的實(shí)踐了.
當然如果不知道如何依據業(yè)務(wù)屬性來(lái)做相等判斷時(shí),只要這樣:
在BaseEntity中,根據id來(lái)覆寫(xiě)equals和hashcode
有特別需要的子類(lèi)中,根據業(yè)務(wù)屬性來(lái)做equals和hashcode