You must take care when implementing Object.equals() for Java objects being persisted using Hibernate. Well, this is no surprise because the Hibernate documentation says so. However, here is a subtle gotcha that is not emphasized in the current Hibernate documentation. I ran across some classes whose equals() method tested that the other object was of exactly the same class as the target object. This is unusual, because most equals() methods settle for instanceof. The ones that used strict equality were broken because Hibernate's decorated versions of classes might be used in place of the actual classes. Consider, for example this stack trace:
TBProductCatg(AbstractPersistentObject).equals(Object)
AbstractPersistentObject$$FastClassByCGLIB$$1ce0f1a2.invoke(int, Object, Object[])
MethodProxy.invoke(Object, Object[])
CGLIBLazyInitializer.intercept(Object, Method, Object[], MethodProxy)
TBProductCatg$$EnhancerByCGLIB$$ec0e8df4.equals(Object)
In this case, the initial call to equals() was passed a decorated object but you can see from the trace that it ultimately was passed to an undecorated version of the class.