javajpaquarkusquarkus-panache

Is Quarkus ever returning an instance of HibernateProxy


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?


Solution

  • 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 {
    }