Hibernate equals and proxy

后端 未结 4 1846
忘了有多久
忘了有多久 2020-12-29 09:12

I have one BaseEntity which abstracts id and version property. this class also implements hashcode and equals based on PK (id) property.

BaseEntity{

    Lo         


        
4条回答
  •  悲哀的现实
    2020-12-29 09:51

    To be able to lazy-load the a.b association, Hibernate sets the b field in a to a proxy. The proxy is an instance of a class that extends B, but is not B. So, your equals() method will always fail when comparing a non-proxy B instance to a proxy B instance, because it compares the classes of both objects:

    if (getClass() != obj.getClass())
        return false;
    

    In the case of Hibernate entities, you should replace this with

    if (!(obj instanceof B)) {
        return false;
    }
    

    Also, note that

    • Hibernate recommends not implementing equals() and hashCode() by using the ID, but rather by using a natural identifier. Implementing it with IDs can cause problems because entities don't have an ID until they're saved and the ID is generated
    • When using entity inheritance, the problem is even worse. Suppose B is a superclass of two sub-entities B1 and B2. Hiberante can't know which type (B1 or B2) is a.b before loading it. So a.b will be initialized to a proxy which is a subclass of B, but is not a subclass of B1 or B2. So the hashCode() and equals() methods should be implemented in B, but not be overridden in B1 and B2. Two B instances should be considered equal if they're instances of B, and have the same identifier.

提交回复
热议问题