I know this is an age-long topic with countless posts about it, but I can't seem to find a clear answer to this question.
When dealing with entities with natural IDs, why is an equals
/hashCode
implementation based on all relevant fields (as if it was a plain data object) seemingly not an option? This post, this post, and some of the answers in this Stack Overflow thread suggest to only use the natural ID in equals
/hashCode
. This does not seem to take into consideration comparisons against transient/detached entities. For instance, given the following class:
public class Currency {
private String code; // e.g. "USD"
private String name; // e.g. "United States Dollar"
@Override
public boolean equals(Object obj) {
return obj instanceof Currency other && Objects.equals(code, other.code);
}
@Override
public int hashCode() {
return Objects.hashCode(code);
}
}
Equality check between Currency{code=USD, name=United States Dollar}
and Currency{code=USD, name=Foobar Dollar}
(if the latter is assumed to be transient/detached, then this situation is realistic) will yield true
, which is probably not correct.
The "3rd option" in the previously linked SO thread, alongside its discussions about whether the equals
/hashCode
in that case is "broken" or not, lead me to believe that an implementation based on all relevant fields is valid after all, though it is not clear to me.
Clarification: "relevant" fields are those that represent the entity's properties, i.e. not fields that are some transient implementation detail, e.g. some cached computation.
If I have erred in any of my assumptions or have missed something obvious, please correct me :)