1

I´m currently building a web app with Spring Boot and until now I have one datasource. Now I want to add a second one using JNDI. To do so I created a configuration class for each datasource that is supposed to fetch the properties using JNDI. Unfortunately I keep getting an error telling me that the reportingEntityManager cannot be created. Before embedding the second datasource everything worked fine.

I tried the solutions suggested in Configuring two datasources by jndi lookup with Springboot + NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean and tried several tutorials but it won´t work.

I´ve been trying to solve this problem for two days now and I´m running out of ideas on what else to try. Would be great if someone has an idea or can at least help me understanding whats wrong, thanks!

Config class for the first datasource

@EnableConfigurationProperties
@EnableTransactionManagement
@EnableJpaRepositories(
        basePackages = {"com.project.support.database.research.repositories"},
        entityManagerFactoryRef = "researchEntityManagerFactory",
        transactionManagerRef = "researchTransactionManager")
@PropertySource("classpath:application.properties")
public class ResearchDbConfig {

    @Primary
    @Bean(name = researchDataSourceProperties")
    @ConfigurationProperties("research.spring")
    public DataSourceProperties dataSourceProperties() {
        return new DataSourceProperties();
    }

    @Primary
    @Bean(name = "researchEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("researchDataSource") DataSource researchDataSource) {
        return builder.dataSource(researchDataSource)
                .packages("com.project.support.database.research.entities")
                .persistenceUnit("research")
                .build();
    }

    @Primary
    @Bean(name = "researchTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("researchEntityManagerFactory") EntityManagerFactory researchEntityManagerFactory) {
        return new JpaTransactionManager(researchEntityManagerFactory);
    }

}

Config class for the second datasource

@Configuration
@EnableConfigurationProperties
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "reportingEntityManagerFactory",
        transactionManagerRef = "reportingTransactionManager",
        basePackages = {"com.project.support.database.reporting.repositories"})
@PropertySource("classpath:application.properties")

public class ReportingDbConfig {

    @Bean
    public DataSource secondaryDataSource() {
        JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
        return dataSourceLookup.getDataSource(jndiSecondary().getJndiName());
    }

    @Bean(name = "reportingEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
            EntityManagerFactoryBuilder builder,
            @Qualifier("reportingDataSource") DataSource reportingDataSource) {
        return builder.dataSource(reportingDataSource)
                .packages("com.project.support.database.reporting.entities")
                .persistenceUnit("reporting")
                .build();
    }

    @Bean(name = "reportingTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("reportingEntityManagerFactory") EntityManagerFactory reportingEntityManagerFactory) {
        return new JpaTransactionManager(reportingEntityManagerFactory);
    }
}

application.properties

research.spring.datasource.jndi-name=jdbc/research
reporting.spring.datasource.jndi-name=jdbc/reporting

Error Message

26-Aug-2020 08:05:23.580 SEVERE [RMI TCP Connection(16)-192.168.178.46] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method [manageApp]
 java.lang.IllegalStateException: Error starting child
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:716)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1729)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:289)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:457)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:406)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:289)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/support]]
    at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:441)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:713)
    ... 41 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportingEntityManager' defined in class path resource [com/project/support/configuration/PersistenceReportingEntityAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1630)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1082)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:300)
    at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
    at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:131)
    at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:91)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5139)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    ... 42 more
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:271)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:233)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:242)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:861)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:384)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1688)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1626)
    ... 61 more
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100)
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:259)
    ... 78 more

26-Aug-2020 08:05:23.581 SEVERE [RMI TCP Connection(16)-192.168.178.46] org.apache.tomcat.util.modeler.BaseModelMBean.invoke Exception invoking method [createStandardContext]
 javax.management.RuntimeOperationsException: Exception invoking method [manageApp]
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:298)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:457)
    at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:406)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:289)
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
    at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
    at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
    at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
    at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
    at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
    at sun.rmi.transport.Transport$1.run(Transport.java:200)
    at sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalStateException: Error starting child
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:716)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:695)
    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1729)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:289)
    ... 33 more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/support]]
    at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:441)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:198)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:713)
    ... 41 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reportingEntityManager' defined in class path resource [com/project/support/configuration/PersistenceReportingEntityAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1630)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:481)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:308)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1082)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:857)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:123)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:666)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:353)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:300)
    at org.springframework.boot.web.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:151)
    at org.springframework.boot.web.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:131)
    at org.springframework.boot.web.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:91)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:169)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5139)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    ... 42 more
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:271)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:233)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210)
    at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:51)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:242)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.handleTypes(MetadataBuildingProcess.java:352)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:111)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:861)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:888)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:384)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:371)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:336)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1688)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1626)
    ... 61 more
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100)
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:259)
    ... 78 more
Greta
  • 300
  • 1
  • 10
  • You don't need the `JndiPropertyHolder` as the `jndi-name` property is already on the `DataSourceProperties`, you are trying to outsmart Spring Boot there (how to add multiple datasources can be seen [here](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-two-datasources) and you will benefit from all he Spring Boot goodness. This might also help you in resolving the `EntityManagerFactory` error. However you should now also have 2 of those and without seeing the config of them help is limited. Also remove the `@PropertySource` as that is already being loaded. – M. Deinum Aug 26 '20 at 07:05
  • @M. Deinum thanks for the answer. I removed the PropertySource-annotation in both configuration-classes now. In the documentation the datasources are not configured with jndi, are they? What config is missing? – Greta Aug 26 '20 at 07:20
  • The configuration (as mentioned in the docs) applies to both jndi and non-jndi. The config that is missing is the config for the `EntityManagerFactory` instances. You configure 2 datasources so you should configure 2 entitymanagerfactories as well. – M. Deinum Aug 26 '20 at 07:28
  • @M. Deinum I added the EntityManagerFactory and TransactionManager configurations and removed the JndiPropertyHolder. Unfortunately the same error is still there... – Greta Aug 26 '20 at 08:11
  • Have you actually taken a look at the stack trace? **Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set**. Set the `hibernate.dialect` property or set `spring.jpa.database=` in your `application.properties`. – M. Deinum Aug 26 '20 at 08:17
  • I have, the dialect is set. – Greta Aug 26 '20 at 09:30
  • Not according to that error message and I doubt that error message is wrong. Can you add your `application.properties`? – M. Deinum Aug 26 '20 at 09:45
  • in application.properpties, append the jndi name & try as `research.spring.datasource.jndi-name=java:comp/env/jdbc/research` – Dinesh Dontha Aug 26 '20 at 11:01

1 Answers1

1

This answer summarizes my own findings regarding approximately the same problem that is stated here. I have picked the most recent relevant question, because things might have changed and behave differently now.

My own setup was Spring Boot 2.4.12, with my project compiled as WAR artifact and deployed to an external Tomcat with HikariCP and Oracle libraries already in its classpath, and Oracle connection defined as global resource in Tomcat's server.xml.

About the final inner exception from the stacktrace of the OP:

Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

I have an impression that the configuration was not read correctly at all. In my case, this message appeared too, but at that time I had already found a working solution - so I didn't investigate it thoroughly. As I understand it, it is very possibly that Spring Boot tries to initialize with default values the rest of the data source properties that are not set explicitly in the configuration, and these default values do not match.

In my case, the only datasource and JNDI-related thing in application.properties was

spring.datasource.jndi-name = java:/comp/env/jdbc/MyOracleHikariDS

In my specific scenario, there was a second data source hidden deep inside secondary libraries that I was using, that pointed to an embedded H2 instance for use as a cache. So there was a reference to H2 library in the classpath, which Spring Boot somehow seemed to pick up as the default datasource. So I had to force (via explicit @Primary declaration) the primary datasource to point to my real primary datasource, which needed to be defined via JNDI.

I think I found out, with the help of multiple M. Deinum comments and answers to other questions, that it was not required to also provide implementations of TransactionManager and EntityManagerFactoryBean, when I only wanted to define a specific data source as @Primary. In my case the problem was how that data source was created, once I took its creation upon myself, doing it manually.

In my experience, something went wrong, when I returned my datasource using the following code:

@Bean
@Primary
@ConfigurationProperties(prefix="spring.datasource")
public DataSource dataSource() {
   return DataSourceBuilder.create().build();
}

At first I thought that at the time when Spring tries to initialize the data source as part of its context initialization, Tomcat hasn't yet initialized its own JNDI resource - so I tried to play with @Lazy and proxies and what not, but this wasn't finally the case.

My private conclusion (have NOT confirmed this) is that @ConfigurationProperties takes the properties literally and overwrites the properties we get from JNDI lookup. The only thing I got working is the following:

@Configuration
@EnableJpaRepositories(basePackages = "com.myproject.repositories.primary",
        entityManagerFactoryRef = "primaryEMF",
        transactionManagerRef = "primaryTM")
public class JpaPrimaryConfig {
   
   @Value("${spring.datasource.jndi-name}")
   String jndiName;

   @Bean(destroyMethod = "")
   @Primary
   public DataSource dataSource() {
      JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
      DataSource ds = dataSourceLookup.getDataSource(jndiName);
      return ds;
   }

   // we have to bind different entities to different data sources - we can do this via entity managers
   @Primary
   @Bean(name = "primaryEMF")
   public LocalContainerEntityManagerFactoryBean primaryEMF(EntityManagerFactoryBuilder builder) {
      return builder.dataSource(dataSource()).packages(DummyEntity.class).build();
   }

   @Primary
   @Bean(name = "primaryTM")
   public PlatformTransactionManager primaryTM(final @Qualifier("primaryEMF") LocalContainerEntityManagerFactoryBean emf) {
      return new JpaTransactionManager(emf.getObject());
   }

}

Note that the above is an example; in my working project I didn't have to use @EnableJpaRepositories as the second data source I needed didn't use Spring-specific repository objects.

Another useful thing to check, apart from upping HikariCP log level (logging.level.com.zaxxer=DEBUG), is to make sure your servlet container really has those JNDI resources defined. This can be done via jconsole for a local Tomcat. It's also useful to start Tomcat without any applications deployed to see that it doesn't complain about initial creation of connection pools.

blackgreen
  • 34,072
  • 23
  • 111
  • 129
hello_earth
  • 1,442
  • 1
  • 25
  • 39