Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should equals and hashcode be implemented when using JPA and Hibernate

How should model class's equals and hashcode be implemented in Hibernate? What are the common pitfalls? Is the default implementation good enough for most cases? Is there any sense to use business keys?

It seems to me that it's pretty hard to get it right to work in every situation, when lazy fetching, id generation, proxy, etc are taken into account.

like image 388
egaga Avatar asked Oct 28 '09 17:10

egaga


People also ask

How does hibernate use equals and hashCode?

Java's default implementation of the equals() and hashCode() methods are based on the object's identity. That means that no two objects are equal and all of them have a different hash code value. Hibernate makes sure to return the same object if you read the same entity twice within a Session.

Do JPA entities need equals and hashCode?

Introduction. As previously explained, using the JPA entity business key for equals and hashCode is always best choice. However, not all entities feature a unique business key, so we need to use another database column that is also unique, as the primary key.

Do you need to override the equals and hashCode method in your entity classes?

You must override hashCode() in every class that overrides equals(). Failure to do so will result in a violation of the general contract for Object. hashCode(), which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.


1 Answers

Hibernate has a nice and long description of when / how to override equals() / hashCode() in documentation

The gist of it is you only need to worry about it if your entity will be part of a Set or if you're going to be detaching / attaching its instances. The latter is not that common. The former is usually best handled via:

  1. Basing equals() / hashCode() on a business key - e.g. a unique combination of attributes that is not going to change during object (or, at least, session) lifetime.
  2. If the above is impossible, base equals() / hashCode() on primary key IF it's set and object identity / System.identityHashCode() otherwise. The important part here is that you need to reload your Set after new entity has been added to it and persisted; otherwise you may end up with strange behavior (ultimately resulting in errors and / or data corruption) because your entity may be allocated to a bucket not matching its current hashCode().
like image 130
ChssPly76 Avatar answered Oct 12 '22 07:10

ChssPly76