讨论引发自这里:
http://www./topic/8946 以下是我自己的感触。 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 |
|
来自: moonboat > 《hibernate》