After reading up on (again, should have done this a long time ago) implementing equals and hashcode correctly i came to these conclusions,that works for me:
If pre JDK 7: Prefer using Apache commons equalsbuilder and hashcodebuilder. (or Guava). Their javadocs contain examples of how to use them in good way.
If JDK 7++: Use the new Objects utility class
But, If writing for hibernate some special requistes appear (see sources farther down) Amongst them are the recommended usage of instanceof instead of getClass, due to hibernate creating proxys of subclasses that are lazy-loaded.
But as i understand, if doing this another potential problem occurs: The reason to use getClass is to ensure the symmetric property of the equals contract. JavaDocs:
*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.*
And by using instanceof, it's possible to not be symmetric. Example: B extends A. A's equals does an instanceof check of A. B's equals does an instanceof check of B. Give A a and B b:
a.equals(b) --> true b.equals(a) --> false
How to implement equals with hibernate without risking losing the symmetric property? It seems i'm not safe when using getClass, and i'm not safe when using instanceof?
Is the answer to never add significant members to subclasses, and then be safe in using instanceof (for hibernate that is)?
Sources i read:
What issues should be considered when overriding equals and hashCode in Java?
Items 7 and 8 in Josh Blochs excellent book "Effective Java", http://web.archive.org/web/20110622072109/http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf
About Java 7: http://www.javacodegeeks.com/2012/11/guavas-objects-class-equals-hashcode-and-tostring.html