Whimusical
Whimusical

Reputation: 6649

Object equality/hashcode vs JPA/Hibernate entity equality/hashcode

After reading a bit on the topic, I am a bit lost on the Hibernate/JPA requirements for @Entity equality. Do I really have to adjust my @EqualsAndHashCode to make my entities equal based on the db uniqueness still in 2020? What's the point of the @Id metannotation then?

I need to be able to compare my entities at object level, so for now I just implemented my EqualsAndHashCode according to all fields besides @Id.

What are exactly the problems I can face if I keep on with that approach? Isn't anyway the db gonna throw an exception if for some reason Hibernate tries to store or mix 2 entities that have same @Id but are not equals with my implementation? Is it really a risk? I am pretty sure Ive seen in the past a lot of projects with proper tests and noone defining any particular @EqualsAndHashCode, so by default is just comparing the instances, and those projects passed all kind of CRUD tests green, and had no bugs on production

Upvotes: 1

Views: 527

Answers (1)

amseager
amseager

Reputation: 6391

Basically, you'd get some problems when you have bi-directional relationships between entities. For example, if Entity1 has @OneToMany access to Entity2, and Entity2 has @ManyToOne access to EntityId, and both of these entities have @EqualsAndHashcode without specifying fields (i.e., equals and hashcode are generated for all fields including those for relations). In this case, you'd have a circular reference, hence a StackOverflow exception.

In order to avoid that, you can rely only on a field with @Id for constructing equals and hashcode (there are some examples with this approach in hibernate docs). But in this case, you'd get another kind of problems, e.g. if you store transient entities with auto-generated ids in a set (as child entities for some parent one), it wouldn't work correctly because the id field will be null in this case. Probably, you'd need to use some other fields in equals and hashcode in this case.

So, there is no correct answer to this question. You need to make a decision every time you construct your entities.

Upvotes: 1

Related Questions