I have a domain object called User. Properties of user include ssoId, name, email, createdBy, createdDate and userRole. Of these, ssoId must be unique in the sense no two users can have the same sso id. So my equals method checks for the sso id and returns either true or false.
@Override public boolean equals(Object o) {
if (!(o instanceof User))
return false;
return user.getSsoId().equals((User)o.getSsoId());
}
What I feel is that this is an incorrect implementation, though it is correct as far as the business rules are concerned. The above implementation will return true for two objects with same sso id but with different values for say name or email or both. Should I change my equals contract to check the equality of all fields? What is your suggestion?
This is (almost) correct for "technical equality", but not for "natural equality". To achieve top technical equality, you should also test the reflexive
o == this. It may happen that the object isn’t persisted in DB yet and thus doesn’t have a technical ID yet. E.g.For "natural equality" you should rather compare all non-technical properties. For "real world entities" this is after all more robust (but also more expensive) than technical equality.
True, that’s lot of code when there are a lot of properties. A bit decent IDE (Eclipse, Netbeans, etc) can just autogenerate
equals(),hashCode()(and alsotoString(), getters and setters) for you. Take benefit of it. In Eclipse, rightclick code and peek the Source (Alt+Shift+S) menu option.See also: