Search code examples
javaspringspring-webfluxr2dbchibernate-reactive

Using Hibernate-Reactive and together R2DBC in one project


I am currently working on a project using Spring-Webflux and R2DBC. I am using an OracleDB 19c and corresponding drivers for R2DBC. Since Hibernate went reactive I want to try it in the existing project - so it needs to run next to R2DBC (for hibernate I used vertx-oracle). But when starting the application I get ClassNotFoundExceptions:

Exception in thread "main" java.lang.NoClassDefFoundError: org/hibernate/engine/jdbc/mutation/spi/MutationExecutorService
    at org.hibernate.reactive.provider.impl.ReactiveServiceInitiators.buildInitialServiceInitiatorList(ReactiveServiceInitiators.java:122)
    at org.hibernate.reactive.provider.impl.ReactiveServiceInitiators.<clinit>(ReactiveServiceInitiators.java:60)
    at org.hibernate.reactive.provider.ReactiveServiceRegistryBuilder.defaultReactiveInitiatorList(ReactiveServiceRegistryBuilder.java:135)
    at org.hibernate.reactive.provider.ReactiveServiceRegistryBuilder.forJpa(ReactiveServiceRegistryBuilder.java:46)
    at org.hibernate.reactive.provider.impl.ReactiveEntityManagerFactoryBuilder.getStandardServiceRegistryBuilder(ReactiveEntityManagerFactoryBuilder.java:39)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:249)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:189)
    at org.hibernate.reactive.provider.impl.ReactiveEntityManagerFactoryBuilder.<init>(ReactiveEntityManagerFactoryBuilder.java:33)
    at org.hibernate.reactive.provider.ReactivePersistenceProvider.getEntityManagerFactoryBuilder(ReactivePersistenceProvider.java:151)
    at org.hibernate.reactive.provider.ReactivePersistenceProvider.getEntityManagerFactoryBuilderOrNull(ReactivePersistenceProvider.java:102)
    at org.hibernate.reactive.provider.ReactivePersistenceProvider.createEntityManagerFactory(ReactivePersistenceProvider.java:50)
    at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
    at jakarta.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at org.hibernate.reactive.example.nativesql.Main.main(Main.java:38)
Caused by: java.lang.ClassNotFoundException: org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 14 more

Process finished with exit code 1

It seems like not all Classes needed are delivered with the hibernate-reactive-core (2.2.0.Final) depenedency. Am I missing something in the documentation or is this some sort of unexpected behaviour?

I tried to import the missing MutationExecutorService interface by adding the dependency

        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.4.0.Final</version>
        </dependency>

to the pom.xml which kind of worked - the class was imported but then I faced problems running both: hibernate and R2DBC. This resulted in a connection timeout for every hibernate-session I tried to open.

I also tried to use the given minimum project from hibernate-reactive examples with less dependencies and even then I faced java.lang.ClassNotFoundException: org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService so that should not be caused by R2DBC.

Do you have some experience and advise for working with hibernate-reactive and R2DBC in one project? And is the missing class normal behaviour or is this an error that should not happen?

Edit I tried the dependencies recommended by [https://stackoverflow.com/a/77620095/23052670)[Davide D'Alto] (hibernate-core 6.3.2.Final + hibernate-reactive-core 2.1.0.Final).

I am still getting a Spring startup freezing for a few seconds and then responding with the Error-Log containing a Timeout.

Edit 2 Even with preparing a SessionFactory-Bean by myself in a @Configuration class I get Timeouts when starting my application.

Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: io.vertx.core.impl.NoStackTraceThrowable: Timeout

Is this a general Problem to vertx-oracle? Online I've found vertx-postgres examples but no oracle.

Edit 3

I managed to get a connection to a OracleDB with version 21.3c (also a docker container). Still I get an Error: WARN vert.x-eventloop-thread-0 org.hibernate.reactive.provider.service.ReactiveGenerationTarget HR000021: DDL command failed [java.lang.NoClassDefFoundError: oracle/jdbc/OracleCommonPreparedStatement] and therefore the queries have no effect on the database.

I was able to fix that Problem again with a dependency of com.oracle.databas.jdbc.ojdbc11-23.2.0.0.


Solution

  • I figured out how to run it with OracleDB. I took following steps:

    1. It seems like Hibernate-Reactive is not compatible with OracleDB 19c at the moment. Using Version 21c worked out (so 'tested with' within project-README should be taken serious at this point)
    2. Although a connection to the Database was possible I wasn't able to write to it (at least within autogeneration at startup). This could be fixed by adding following dependency to my pom.xml:
        <dependency>
                <groupId>com.oracle.database.jdbc</groupId>
                <artifactId>ojdbc11</artifactId>
                <version>23.2.0.0</version>
        </dependency>
    

    After these steps the connection was established and the autogeneration worked.