vladmihalcea / hypersistence-optimizer

Hypersistence Optimizer allows you to get the most out of JPA and Hibernate. By scanning your application configuration and mappings, Hypersistence Optimizer can tell you what changes you need to do to speed up your data access layer.
https://vladmihalcea.com/hypersistence-optimizer/
Apache License 2.0
306 stars 43 forks source link

[QUARKUS 3] The Hibernate SessionFactory is not decorated by Hypersistence Optimizer, and, for this reason, the runtime checks will be disabled #208

Open Vinche59 opened 1 year ago

Vinche59 commented 1 year ago

Hello,

With Quarkus 3.0.3 (Hibernate 6.2.1.Final + postgresql), I always got:

The Hibernate SessionFactory is not decorated by Hypersistence Optimizer, and, for this reason, the runtime checks will be disabled.

And I don´t understand what I'm doing wrong :-)

I created a reproducer here : https://github.com/Vinche59/hypersistence-optimizer-quarkus3.0.3

You can run it with: mvn integration-test

Thanks in advance for your help.

vladmihalcea commented 1 year ago

Thanks for letting me know. I will investigate it and see what's needed to be done to make it work.

vladmihalcea commented 1 year ago

@Vinche59 Unfortunately, runtime scanning cannot work for Quarkus because they are not using the Hibernate EntityManagerFactoryBuilderImpl to build the EntityManagerFactory, which would allow Hypersistence Optimizer to decorate the SessionFactory via its own SessionFactoryBuilder.

Instead, they created their own FastBootEntityManagerFactoryBuilder that builds the SessionFactory like this:

public EntityManagerFactory build() {
    try {
        SessionFactoryOptionsBuilder optionsBuilder = this.metadata.buildSessionFactoryOptionsBuilder();
        this.populate(this.persistenceUnitName, optionsBuilder, this.standardServiceRegistry);
        return new SessionFactoryImpl(this.metadata, optionsBuilder.buildOptions(), this.metadata.getTypeConfiguration().getMetadataBuildingContext().getBootstrapContext());
    } catch (Exception var2) {
        throw this.persistenceException("Unable to build Hibernate SessionFactory", var2);
    }
}

Notice that the SessionFactoryImpl is hardcoded and cannot be decorated by the SessionFactoryBuilder.

On the other hand, this works fine with Spring or plain Jakarta EE apps.

For instance, the Spring HibernatePersistenceProvider builds the SessionFactory, like this:

public static EntityManagerFactoryBuilder getEntityManagerFactoryBuilder(
        PersistenceUnitDescriptor persistenceUnitDescriptor,
        Map integration,
        ClassLoader providedClassLoader) {
    return new EntityManagerFactoryBuilderImpl( persistenceUnitDescriptor, integration, providedClassLoader );
}

So, the only way to make this work is if Quarkus switches to using something similar to the Hibernate Core EntityManagerFactoryBuilder.

vladmihalcea commented 1 year ago

I created this Quarkus issue. If they fix it, the Hypersistence Optimizer will be able to declare the SessionFactory and runtime scanning will be possible.

Vinche59 commented 1 year ago

Thank you for your investigation @vladmihalcea and for opening the quarkus issue.

vladmihalcea commented 1 year ago

You're welcome.