1

I am trying to retrieve a JPA EntityManager from Spring's LocalContainerEntityManagerFactoryBean using the Hibernate OGM persistence provider but I am getting the following error when I attempt to created an EntityManager from the injected EntityManagerFactory:

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:768) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]
    at chelsea.databaseTest.DatabaseTestApplication.main(DatabaseTestApplication.java:30) [classes/:na]
Caused by: java.lang.IllegalArgumentException: methods with same signature getSessionFactory() but incompatible return types: [interface org.hibernate.ogm.OgmSessionFactory, interface org.hibernate.engine.spi.SessionFactoryImplementor]
    at sun.misc.ProxyGenerator.checkReturnTypes(ProxyGenerator.java:712) ~[na:1.8.0_232]
    at sun.misc.ProxyGenerator.generateClassFile(ProxyGenerator.java:461) ~[na:1.8.0_232]
    at sun.misc.ProxyGenerator.generateProxyClass(ProxyGenerator.java:339) ~[na:1.8.0_232]
    at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:639) ~[na:1.8.0_232]
    at java.lang.reflect.Proxy$ProxyClassFactory.apply(Proxy.java:557) ~[na:1.8.0_232]
    at java.lang.reflect.WeakCache$Factory.get(WeakCache.java:230) ~[na:1.8.0_232]
    at java.lang.reflect.WeakCache.get(WeakCache.java:127) ~[na:1.8.0_232]
    at java.lang.reflect.Proxy.getProxyClass0(Proxy.java:419) ~[na:1.8.0_232]
    at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:719) ~[na:1.8.0_232]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator.createProxy(ExtendedEntityManagerCreator.java:251) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator.createProxy(ExtendedEntityManagerCreator.java:206) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator.createApplicationManagedEntityManager(ExtendedEntityManagerCreator.java:110) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:501) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:680) ~[spring-orm-5.2.0.RELEASE.jar:5.2.0.RELEASE]
    at com.sun.proxy.$Proxy58.createEntityManager(Unknown Source) ~[na:na]
    at chelsea.databaseTest.DatabaseTestApplication.run(DatabaseTestApplication.java:49) [classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784) [spring-boot-2.2.0.RELEASE.jar:2.2.0.RELEASE]

I am trying to implement this outside of a Java EE container, which I believe is possible based on what I have researched. I have tried upgrading/downgrading Hibernate and Spring versions, thinking it may be a compatibility issue, but have not had any luck. Any guidance would be much appreciated!

persistence.xml

<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
  version="2.0">
    <persistence-unit name="ogm-mongodb" transaction-type="JTA">
        <!-- Use Hibernate OGM provider: configuration will be transparent -->
        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>
        <properties>
            <property name="hibernate.transaction.jta.platform" value="JBossTS" />
            <property name="hibernate.ogm.datastore.provider" value="mongodb" />        
            <property name="hibernate.ogm.datastore.database" value="TestDB" />
            <property name="hibernate.ogm.datastore.grid_dialect" value="org.hibernate.ogm.datastore.mongodb.MongoDBDialect"/>
            <property name="hibernate.ogm.datastore.create_database" value="true" />
        </properties>
    </persistence-unit>
</persistence>

MongoConfig.java

@Configuration
public class MongoConfig 
{
    @Bean(name = "entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean mongoEntityManager() throws Throwable 
    {
        LocalContainerEntityManagerFactoryBean emf= new LocalContainerEntityManagerFactoryBean();
        entityManager.setPersistenceUnitName("ogm-mongodb");
        return emf;
    }
}

TestApp.java

@SpringBootApplication
public class TestApp implements CommandLineRunner
{
    @PersistenceUnit
    EntityManagerFactory emf;

    public static void main(String[] args) 
    {
        SpringApplication.run(TestApp.class, args);
    }

    @Override
    public void run(String... args) throws Exception
    {       
        Mission test = new Mission("Test Mission A");
        test.setLogin(LoginMode.OPERATOR);

        if(emf != null) 
        {
           TransactionManager tm = com.arjuna.ats.jta.TransactionManager.transactionManager();
           tm.begin();
           EntityManager em = emf.createEntityManager(); //ERROR HAPPENS HERE
           em.persist(test);
           em.close();
           tm.commit();
        }   
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>chejohn</groupId>
    <artifactId>databaseTest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>databaseTest</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    <dependency>
        <groupId>org.hibernate.ogm</groupId>
        <artifactId>hibernate-ogm-mongodb</artifactId>
        <version>5.4.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.3.6.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.narayana.jta</groupId>
        <artifactId>narayana-jta</artifactId>
        <version>5.10.4.Final</version>
    </dependency>

        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>javax.persistence-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.1-api</artifactId>
            <version>1.0.2.Final</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

chejohn131
  • 11
  • 2

2 Answers2

0

You should inject EntityManager directly instead of injecting EntityManagerFactory :

@PersistenceContext
private EntityManager entityManager;
Fabien
  • 974
  • 9
  • 14
0

I suspect there are multiple different versions of Hibernate ORM on your classpath and Hibernate OGM is taking the wrong one. That's why the method getSessionFactory() has an unexpected signature.

UPDATE: Spring Boot 2.2.0 expects Hibernate ORM 5.4.6.Final, OGM uses 5.3.6.Final

Davide D'Alto
  • 7,421
  • 2
  • 16
  • 30
  • Hmm...I suspected this may be the issue, but I've completely searched my maven dependency stack and only Hibernate 5.3.6 is referenced anywhere. – chejohn131 Jun 01 '20 at 19:54