如何实现与hibernate相等而不会失去对称属性的风险?

时间:2013-02-10 20:50:10

标签: java hibernate java-7 hashcode instanceof

在阅读之后(再次,应该已经做了很久以前)正确实现了equals和hashcode我得出了这些结论,这对我有用:

如果是JDK 7之前:更喜欢使用Apache commons equalsbuilder和hashcodebuilder。 (或番石榴)。 他们的javadoc包含了如何以良好的方式使用它们的例子。

如果是JDK 7 ++ :使用新的Objects实用程序类

但是,如果为hibernate写作会出现一些特殊的请求(请参阅更远的来源) 其中推荐使用 instanceof 而不是 getClass ,因为hibernate创建了延迟加载的子类的代理。

但据我所知,如果这样做会发生另一个潜在的问题:使用getClass的原因是为了确保equals合约的对称属性。的JavaDoc:

*It is symmetric: for any non-null reference values x and y, x.equals(y) 
 should return true if and only if y.equals(x) returns true.*

通过使用instanceof,它可能不是对称的。 示例:B扩展A. A的等于A的检查实例.B的等于检查B的实例。给A和B b:

a.equals(b) - >真正 b.equals(a) - >假

如何使用hibernate实现equals而不会失去对称属性的风险?使用getClass时我似乎不安全,使用instanceof时我不安全吗?

答案是永远不要将重要成员添加到子类,然后使用instanceof是安全的(对于hibernate)?

我读到的消息来源:

What issues should be considered when overriding equals and hashCode in Java?

Josh Blochs的第7和第8项优秀书籍“Effective Java”,http://web.archive.org/web/20110622072109/http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf

关于Java 7:http://www.javacodegeeks.com/2012/11/guavas-objects-class-equals-hashcode-and-tostring.html

3 个答案:

答案 0 :(得分:4)

如果要比较equals方法中两个对象的类,可以在比较它们之前对两个对象使用Hibernate.getClass。那你就不会遇到麻烦,例如比较对象和对象的hibernate代理时。

答案 1 :(得分:3)

在进行了一些调查后,我总结了这个问题:

  • 使用instanceof,您永远不能将重要成员添加到子类。( 没有办法扩展可实例化的类并添加值组件,同时保留equals合约(Bloch)
  • 使用getClass并违反Liskov替换原则

Langers说http://www.angelikalanger.com/Articles/JavaSolutions/SecretsOfEquals/Equals.html

  
      
  • 测试的instanceof仅对最终类是正确的,或者至少方法equals()在超类中是最终的。后者本质上   意味着没有子类必须扩展超类的状态,但可以   仅添加与对象无关的功能或字段   状态和行为,例如瞬态或静态字段。
  •   
     

另一方面,使用getClass()测试的实现总是如此   遵守equals()合同;他们是正确和强大的。他们   然而,在语义上与实现非常不同   使用instanceof测试。使用getClass()的实现不允许   子类与超类对象的比较,甚至不是子类时   不添加任何字段,甚至不想覆盖equals()。   这种“普通的”类扩展例如是添加的   一个子类中的调试打印方法,正是为这个“微不足道”而定义的   目的。如果超类禁止通过混合类型比较   getClass()检查,那么普通的扩展将无法比较   到它的超类。这是否完全取决于问题   类的语义和扩展的目的。

摘要 - 使用finalof和final for equals可以避免破坏对称性,并避免出现休眠“代理”问题。

链接

答案 2 :(得分:2)

这是一个有趣的问题 - 在涉及继承时,将equals实现为等价关系并非易事。见Martin Odersky等人的this in-depth post。关于实现对象平等。