Hibernate实体的equals和hashcode

讨论引发自这里:
[url]http://www.iteye.com/topic/8946[/url]

以下是我自己的感触。
equals实际上是java判断两个对象是否相等的一个依据;而在set、map这样的存储位置与hashcode的集合中, hashcode起着计算位置的作用,同时又要满足一个约定:equals相等,则hashcode必然相等。

基于以上,hibernate实体的Entity也需要做出如下策略:
1)怎样才是相等实体对象
2)在set、map这样的跟hashcide有关的集合映射时,如何保证相等对象hashcode也相等。

可以看出关键还是如何决定两个实体对象是否相等,至于hashcode其实根据equals去实现的。
许多人提出来用实体对象的id来判断是否相等,这其实源于hibernate的持久对象管理机制。Hibernate利用id属性来管理一类持久对象,对于session中的一类持久对象,id是唯一的,因此id用作某一类持久对象的标识符是合适的。

那么否针对id判断实体相等就是合理的策略了吗?
关键还是看你怎样才认为实体对象是相等的,这个倒不能采取hibernate对id的特殊用法。
如果认为业务属性无所谓,只要id相等就相等,那就完全可以用id作为判断相等的依据。
如果需要根据业务属性来判定,那么id就不是合理的策略,因为很可能id不等但是业务属性都相等。
如果不是那么关心重复的实体对象,因此就不会覆盖equals和hashcode方法,直接沿用Object的也是可以的,实际上很多时候我们都是这样做的。
经过仔细的思考,发现这种提出这种讨论本身都是夸大了问题。equals和hashcode根本不是hibernate提出的新概念和新要求。

针对以上的分析,有没有最佳实践呢?
看看Hibernate in action,有三种方法:
1. 就是的这种用无意义主键id做hashCode/equals
2. 就是用的所有值做hashCode/equals
3. 用一个(或者几个)相对稳定的业务字段做hashCode/equals (比如user, 就用userName).
hibernate 推荐的是第3种, 按照这种推荐的做法, 就不会出现以上说的所有问题了, 这差不多是最佳的实践了.

当然如果不知道如何依据业务属性来做相等判断时,只要这样:
在BaseEntity中,根据id来覆写equals和hashcode
有特别需要的子类中,根据业务属性来做equals和hashcode
阅读更多

没有更多推荐了,返回首页