I'm writing a generic equals/hashCode implementation for my JPA entities in Quarkus. But it seems Quarkus is never returning an instance of HibernateProxy
.
@Override
public final int hashCode() {
return effectiveClass(this).hashCode();
}
private static Class<?> effectiveClass(Object obj) {
return obj instanceof HibernateProxy
? ((HibernateProxy) obj).getHibernateLazyInitializer().getPersistentClass()
: obj.getClass();
}
Even if I have references with lazy loading, there is no proxy and it seems that the entity itself is the proxy after the class has been extended. Can I rely on this, or are there circumstances where Quarkus uses a proxy after all?
Hibernate ORM in Quarkus uses bytecode-enhancement, meaning most of the time it does not need proxies: it just returns an instance of the right class, but with injected bytecode that will make that instance handle lazy-loading transparently.
Proxies are still necessary in some cases though. In particular, you may see proxies when a lazy-loaded association targets an entity that has subclasses: Hibernate ORM cannot know the exact type of the association target without loading it, so it inserts a proxy which will load the actual association target upon lazy loading.
You can try a model like the one below, for example. If you load a Human
from the database, its pet
should be a proxy.
@Entity
public class Human {
@Id
@GeneratedValue
public Long id;
@OneToOne(fetch = FetchType.LAZY)
public Animal pet;
}
@Entity
public class Animal {
@Id
@GeneratedValue
public Long id;
}
@Entity
public class Dog extends Animal {
}
@Entity
public class Cat extends Animal {
}