java:S2162 - Hibernateproxy check is valid

Make sure to read this post before raising a thread here:

Then tell us:

Sonar always flags it with rule java:S2162 because it thinks we are comparing unrelated classes but in my opinion it is a very valid check that should not be flagged. Indeed i am not comparing where sonar thinks i do i just try to resolve the class in question if it is behind a proxy.

    public final boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null) {
            return false;
        }
        Class<?> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer()
                .getPersistentClass() : o.getClass();
        Class<?> thisEffectiveClass = this instanceof HibernateProxy ?
                ((HibernateProxy) this).getHibernateLazyInitializer()
                        .getPersistentClass() : this.getClass();
        if (thisEffectiveClass != oEffectiveClass) {
            return false;
        }
        MyJpaEntity that = (MyJpaEntity) o;
        return getId() != null && Objects.equals(getId(), that.getId());
    }

This code is generated by the jpa buddy plugin

Hey @Nico.Strecker,

Thanks for reporting this issue. I could reproduce the issue with the following snippet.

package org.example;

import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;

import java.util.Objects;

public class MyJpaEntity implements HibernateProxy {
    public final boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null) {
            return false;
        }
        Class<?> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer()
                .getPersistentClass() : o.getClass();
        Class<?> thisEffectiveClass = this instanceof HibernateProxy ?
                ((HibernateProxy) this).getHibernateLazyInitializer()
                        .getPersistentClass() : this.getClass();
        if (thisEffectiveClass != oEffectiveClass) {
            return false;
        }
        MyJpaEntity that = (MyJpaEntity) o;
        return getId() != null && Objects.equals(getId(), that.getId());
    }

    Long getId() {
        return 42L;
    }

    @Override
    public Object writeReplace() {
        return null;
    }

    @Override
    public LazyInitializer getHibernateLazyInitializer() {
        return null;
    }
}

Can you confirm that this is the issue you are seeing? Is the class that contains the equals methods explicitly extending HibernateProxy?

1 Like

@Dorian_Burihabwa
No i can’t, Hibernate uses Byte Buddy to implicitly create a Proxy if i remember correctly

What could help for detection: all entities in spring boot should be Annotated with entity

Let me recap:

  • There is no explicit extends or implements clause on the class
  • The only potential indicator that the equals method is valid is that the class, or a class in its hierarchy, is annotated with @Entity

Is this correct?

I am afraid that is the case because the Proxy is created in the background on runtime.

What then is imported is HibernateProxy that could also be a indicator and class names clould end with entity but in my opinion that is not always the case and should not be considered

In fact, if we correctly detect the comparison (not the class resolution, which is what is flagged), it would work if we only consider the equals method instead of the instanceof class resolution.