When providing #equals
implementation for a UDT in Java one of the conditions is that the passed argument object must be an instance of the current class otherwise we fail-fast return false
see Effective Java (EJ2). However, while using Hibernate 4 we can end up with javassist proxy instances due to lazy loading where this #equals
condition will fail. What would be the best choice to overcome this? The few choices I can think of are:
- extend the
equals
implementation to take into account the proxy case. Cons: maintainability toll, hardwired dependency to Hibernate proxy infrastructure, hacky, entity or domain models should be agnostic to the ORM being used i.e. since they might be reused in different contexts where there is no need for ORM e.g. Swing UI. - check whether it is a proxy before invoking
equals
. Cons: not always possible, i.e., dealing with Collections and implicit invocations ofequals
, e.g., Map. - Refrain from using lazy loading. Cons: not reasonable nor efficient in all use-cases.
UPDATE
Reviewing EJ2 again I believe that the following will work for all scenarios (Type-Type, Type-Proxy, Proxy-Type and Proxy-Proxy) but as pointed out in one of the comments below it may loop forever if the Type is compared to a totally different type e.g. Person.equals(Employee)
and both use the same equals EJ2 criteria.
if (this.getClass() != anObject.getClass())
{
return anObject.equals(this);
}