First, entity equality is a domain detail which is best abstracted away from business code. The best place obviously for this is in the entity itself. Additionally, equality rules often vary based perhaps on entity state or other domain rules and so overriding the equals
method insure those rules are adhered to not only in business code, but collection usage, and hibernate's session management.
Consider a composite-key based entity that uses several fields to consitute equality. Which of the following business code looks more appealing and is the least rigid to change:
public void someBusinessFunction(EntityA e1, EntityA e2) {
if(e1.equals(e2))
throw new SomeEqualityException();
// do logic
}
public void someBusinessFunction2(EntityA e1, EntityA e2) {
if(e1.getId().getFieldA().equals(e2.getId().getFieldA()) &&
e1.getId().getFieldB().equals(e2.getId().getFieldB()) &&
e1.getId().getFieldC().equals(e2.getId().getFieldC())) {
throw new SomeEqualityException();
}
// do logic
}
From a business code perspective, we should not care what constitutes equality. All that code cares about is whether 2 instances of the same class equal one another. What rule is used to determine that use case is irrelevant.
In short, it's just good programming by abstracting details that should be abstracted in the first place.
EDIT
More specific to the Java language itself, the Object
's stock equality only compares whether the two operands point to the same physical instance via the ==
operator. This is only valid if the two instances point to the same memory location.
It is possible to obtain the same domain entity via multiple transactions and therefore would point to two different memory locations because they were once managed by different sessions. In this case, the default equals
method would return false which may not be desired.
By overriding the equals
method, you can explicitly make sure that the above case always returns true
for equality regardless of how the instance was obtained and where it may be stored in memory.
Additionally, the java doc explicitly states that overriding hashCode
should occur when you override equals
to maintain the contract between hashCode
and equals
so that when object equality is true, the hash codes are also equal as well.