When you annotate some JPA Entity with Lombok:
@Entity
@EqualsAndHashCode
public class Person {
IntelliJ Idea will show a suggestion that it is not optimal:
Using @EqualsAndHashCode for JPA entities is not recommended. It can cause severe performance and memory consumption issues.
And it generates the following code:
@Override
public final boolean equals(Object object) {
if (this == object) return true;
if (object == null) return false;
Class<?> oEffectiveClass = object instanceof HibernateProxy ? ((HibernateProxy) object).getHibernateLazyInitializer().getPersistentClass() : object.getClass();
Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
if (thisEffectiveClass != oEffectiveClass) return false;
ConfigAudit that = (ConfigAudit) object;
return getId() != null && Objects.equals(getId(), that.getId());
}
@Override
public final int hashCode() {
return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
}
I just noticed that the hashCode()
is actually called on the class and not on the object. Is this bug?
Javadoc:
If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
Yes, this was made intentionally - with this hashCode()
implementation entities are grouped by classes and then can be compared by equals()
. More details in this article https://jpa-buddy.com/blog/hopefully-the-final-article-about-equals-and-hashcode-for-jpa-entities-with-db-generated-ids/