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

ClassNotFoundException - Hibernate63SessionFactoryBuilderFactory is missing in the 2.8.0 library version #217

Closed loongo closed 7 months ago

loongo commented 7 months ago

Hi, Sorry if this is not the right place, or if I have misconfigured something.

I seem to have an issue when trying to run the optimiser with Spring boot 3.2.0. (See below)

When I imported the trial version 2.7.1 it executed correctly. I couldn't find the previous version 2.7.1 of the full version in the store front so I'm unable to test if that version works, with my config.

@Configuration
@Profile("dev")
public class HypersistenceConfiguration {
    @Bean
    public HypersistenceOptimizer hypersistenceOptimizer(EntityManagerFactory entityManagerFactory) {
        return new HypersistenceOptimizer(
                new JpaConfig(entityManagerFactory));
    }
}

My build.gradle has:

import com.github.gradle.node.npm.task.NpmTask

plugins {
    java
    id("org.springframework.boot") version "3.2.0"
    id("io.spring.dependency-management") version "1.1.3"
    id("com.github.node-gradle.node") version "5.0.0"
    id("io.spring.javaformat") version "0.0.40"
}

java {
    sourceCompatibility = JavaVersion.VERSION_21
    targetCompatibility = JavaVersion.VERSION_21
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

configurations {
    compileOnly {
        extendsFrom(configurations.annotationProcessor.get())
    }
}

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    compileOnly("org.projectlombok:lombok")
    developmentOnly("org.springframework.boot:spring-boot-devtools")
    annotationProcessor("org.projectlombok:lombok")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation("org.springframework.boot:spring-boot-starter-logging")
    testImplementation("org.springframework.modulith:spring-modulith-starter-test")
    implementation("com.github.xeroapi:xero-java:4.29.0")
    implementation("org.springframework.boot:spring-boot-starter-web")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-security")
    runtimeOnly("com.microsoft.sqlserver:mssql-jdbc")
    implementation("com.azure.spring:spring-cloud-azure-starter-active-directory")
    implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
    implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0")
    implementation("org.bitbucket.b_c:jose4j:0.9.3")
    implementation("org.liquibase:liquibase-core")
    implementation("org.apache.poi:poi:5.2.5")
    implementation("org.apache.poi:poi-ooxml:5.2.5")
}

dependencyManagement {
    imports {
        mavenBom("org.springframework.modulith:spring-modulith-bom:1.0.0")
    }
}
dependencies {
    // Import the BOM without specifying type or scope
    dependencyManagement {
        imports {
            mavenBom("com.azure.spring:spring-cloud-azure-dependencies:5.7.0")
        }
    }
}

tasks.withType<Test> {
    useJUnitPlatform()
}

var shouldBuildFrontend = false
tasks {
    bootRun {
        args = listOf("--spring.profiles.active=dev") // Set the active profile to "dev"
    }

    bootJar {
        shouldBuildFrontend = true
        listOf("--spring.profiles.active=production") // Set the active profile to "dev"
        from("../frontend/build") {
            into("public")
        }
    }

    processResources {
        dependsOn("buildFrontend")
    }
}

tasks.register<NpmTask>("buildFrontend") {
    print(shouldBuildFrontend)
    onlyIf { shouldBuildFrontend }
    workingDir = file("../frontend")
    args = listOf("run", "build-prod")
}

node {
    version = "18.17.1"
    npmVersion = "10.2.1"
    workDir = file("../frontend")
}

Results in

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: java.lang.ClassNotFoundException: io.hypersistence.optimizer.hibernate.decorator.Hibernate63SessionFactoryBuilderFactory
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1775) ~[spring-beans-6.1.1.jar:6.1.1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-6.1.1.jar:6.1.1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:523) ~[spring-beans-6.1.1.jar:6.1.1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.1.1.jar:6.1.1]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.1.jar:6.1.1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.1.1.jar:6.1.1]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.1.1.jar:6.1.1]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1173) ~[spring-context-6.1.1.jar:6.1.1]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:936) ~[spring-context-6.1.1.jar:6.1.1]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:616) ~[spring-context-6.1.1.jar:6.1.1]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.2.0.jar:3.2.0]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:753) ~[spring-boot-3.2.0.jar:3.2.0]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:455) ~[spring-boot-3.2.0.jar:3.2.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:323) ~[spring-boot-3.2.0.jar:3.2.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1342) ~[spring-boot-3.2.0.jar:3.2.0]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1331) ~[spring-boot-3.2.0.jar:3.2.0]
    at com.ftg.Backend.main(Backend.java:12) ~[main/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.2.0.jar:3.2.0]
Caused by: java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: io.hypersistence.optimizer.hibernate.decorator.Hibernate63SessionFactoryBuilderFactory
    at io.hypersistence.optimizer.util.ReflectionUtils.handleException(ReflectionUtils.java:921) ~[hypersistence-optimizer-2.8.0-jakarta.jar:na]
    at io.hypersistence.optimizer.util.ReflectionUtils.getClass(ReflectionUtils.java:759) ~[hypersistence-optimizer-2.8.0-jakarta.jar:na]
    at io.hypersistence.optimizer.util.ReflectionUtils.newInstance(ReflectionUtils.java:60) ~[hypersistence-optimizer-2.8.0-jakarta.jar:na]
    at io.hypersistence.optimizer.hibernate.decorator.HypersistenceSessionFactoryBuilderFactory.getSessionFactoryBuilder(HypersistenceSessionFactoryBuilderFactory.java:74) ~[hypersistence-optimizer-2.8.0-jakarta.jar:na]
    at org.hibernate.boot.internal.MetadataImpl.getSessionFactoryBuilder(MetadataImpl.java:179) ~[hibernate-core-6.3.1.Final.jar:6.3.1.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1503) ~[hibernate-core-6.3.1.Final.jar:6.3.1.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75) ~[spring-orm-6.1.1.jar:6.1.1]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[spring-orm-6.1.1.jar:6.1.1]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-6.1.1.jar:6.1.1]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[spring-orm-6.1.1.jar:6.1.1]
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[spring-orm-6.1.1.jar:6.1.1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1822) ~[spring-beans-6.1.1.jar:6.1.1]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1771) ~[spring-beans-6.1.1.jar:6.1.1]
    ... 19 common frames omitted
Caused by: java.lang.ClassNotFoundException: io.hypersistence.optimizer.hibernate.decorator.Hibernate63SessionFactoryBuilderFactory
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526) ~[na:na]
    at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
    at java.base/java.lang.Class.forName(Class.java:534) ~[na:na]
    at java.base/java.lang.Class.forName(Class.java:513) ~[na:na]
    at org.springframework.boot.devtools.restart.classloader.RestartClassLoader.loadClass(RestartClassLoader.java:121) ~[spring-boot-devtools-3.2.0.jar:3.2.0]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526) ~[na:na]
    at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
    at java.base/java.lang.Class.forName(Class.java:534) ~[na:na]
    at java.base/java.lang.Class.forName(Class.java:513) ~[na:na]
    at io.hypersistence.optimizer.util.ReflectionUtils.getClass(ReflectionUtils.java:757) ~[hypersistence-optimizer-2.8.0-jakarta.jar:na]
    ... 30 common frames omitted
vladmihalcea commented 7 months ago

The Trial version will be migrated to version 2.8 in the upcoming days. Currently, only the Full version supports Spring Boot 3.2.

loongo commented 7 months ago

Hi Vlad,

I am running the full version 2.8. and it is the one currently giving me the error.
Version 2.7.1 (trial) was not giving the error. I'm happy to try out the full version of 2.7.1 and see what the result is but I can't see previous versions on the download page

vladmihalcea commented 7 months ago

You need to use the jakarta classifier as explained in the Installation Guide.

If you don't use it, it will use the javax version which doesn't support Hibernate 6.

vladmihalcea commented 7 months ago

@loongo Actually, I checked the jar, and indeed it's missing that part. I will update it and let you know.

loongo commented 7 months ago

Thanks!

vladmihalcea commented 7 months ago

Fixed.

vladmihalcea commented 7 months ago

@loongo The issue was fixed and the 2.8.1 version was released. It should work just fine now.

loongo commented 7 months ago

@loongo The issue was fixed and the 2.8.1 version was released. It should work just fine now.

Downloaded and it's working. Thank you

vladmihalcea commented 7 months ago

I'm glad I could help and stay tuned for more.