如何在 SpringBoot 中使用 JNDI 配置多个数据源?

时间:2021-02-17 21:15:11

标签: java spring spring-boot hibernate

尝试使用 JNDI 配置 2 个数据源,但出现错误。有 2 个包:

1-对于第一个数据源的实体和存储库。

2- 用于第二个数据源的实体和存储库。

我用于配置其中之一的代码:

@Configuration
@PropertySource(value = "classpath:application-prod.properties")
@EnableJpaRepositories(
        basePackages = "com.example.test.repository",
        entityManagerFactoryRef = "applicationEntityManagerFactoryBean",
        transactionManagerRef = "applicationTransactionManager"
)
public class ApplicationDataSourceConfiguration {

    @Value("${spring.datasource.outage.jndi-name}")
    private String applicationJndiDatasourceName;
    private HibernateProperties hibernateProperties;

    @Autowired
    public ApplicationDataSourceConfiguration(HibernateProperties hibernateProperties) {
        this.hibernateProperties = hibernateProperties;
    }

    @Bean
    @Primary
    public DataSource applicationDataSource(){
        JndiDataSourceLookup jndiDataSourceLookup = new JndiDataSourceLookup();
        return jndiDataSourceLookup.getDataSource(applicationJndiDatasourceName);
    }

    @Bean
    @Primary
    public PlatformTransactionManager applicationTransactionManager(){
        JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
        jpaTransactionManager.setEntityManagerFactory(applicationEntityManagerFactoryBean().getObject());
        return jpaTransactionManager;
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean applicationEntityManagerFactoryBean(){
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        factoryBean.setDataSource(applicationDataSource());
        factoryBean.setPackagesToScan("com.example.test.entity");
        factoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());

        factoryBean.setJpaProperties(hibernateProperties.getHibernateProperties());
        factoryBean.afterPropertiesSet();
        return factoryBean;
    }
}

我的 HibernateProperies 类:

@Component
public class HibernateProperties {
    private Environment environment;

    @Autowired
    public HibernateProperties(Environment environment) {
        this.environment = environment;
    }

    public Properties getHibernateProperties() {
        Properties jpaProperties = new Properties();
        jpaProperties.put("hibernate.hbm2ddl.auto", Objects.requireNonNull(environment.getProperty("spring.jpa.hibernate.ddl-auto")));
        jpaProperties.put("hibernate.jdbc.lob.non_contextual_creation", Objects.requireNonNull(environment.getProperty("spring.jpa.properties.hibernate.dialect")));
        jpaProperties.put("hibernate.dialect", Objects.requireNonNull(environment.getProperty("spring.jpa.properties.hibernate.dialect")));
        return jpaProperties;
    }
}

我的 application.properties:

spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.SybaseDialect
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

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

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

以及我的 web.xml 的一部分:

  <resource-ref>
        <res-ref-name>jdbc/app</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

    <resource-ref>
        <res-ref-name>jdbc/prod</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

这是我的堆栈跟踪:

2021 02 17 20:47:51#+00#ERROR#org.springframework.boot.SpringApplication##anonymous#localhost-startStop-1#na#spomcm8y67#setrainer#web##na#na#na#na#Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationEntityManagerFactoryBean' defined in class path resource [com/sap/cloud/se/trainer/app/config/ApplicationDataSourceConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'applicationEntityManagerFactoryBean' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationDataSource' defined in class path resource [com/sap/cloud/se/trainer/app/config/ApplicationDataSourceConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'applicationDataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'java:comp/env/jdbc/app'; nested exception is javax.naming.NamingException: Cannot create resource  object instance due to exception in the object factory [Root exception is javax.naming.NamingException: No persistence configuration available for resource name [jdbc/app], check datasource bindings for this application]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:484)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1108)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:152)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:132)
    at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:92)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5144)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:970)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1840)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    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:836)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'applicationEntityManagerFactoryBean' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationDataSource' defined in class path resource [com/sap/cloud/se/trainer/app/config/ApplicationDataSourceConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'applicationDataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'java:comp/env/jdbc/app'; nested exception is javax.naming.NamingException: Cannot create resource  object instance due to exception in the object factory [Root exception is javax.naming.NamingException: No persistence configuration available for resource name [jdbc/app], check datasource bindings for this application]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
    ... 32 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'applicationDataSource' defined in class path resource [com/sap/cloud/se/trainer/app/config/ApplicationDataSourceConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'applicationDataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'java:comp/env/jdbc/app'; nested exception is javax.naming.NamingException: Cannot create resource  object instance due to exception in the object factory [Root exception is javax.naming.NamingException: No persistence configuration available for resource name [jdbc/app], check datasource bindings for this application]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:484)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.resolveBeanReference(ConfigurationClassEnhancer.java:362)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:334)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration$$EnhancerBySpringCGLIB$$ddb894e1.applicationDataSource(<generated>)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration.applicationEntityManagerFactoryBean(ApplicationDataSourceConfiguration.java:56)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration$$EnhancerBySpringCGLIB$$ddb894e1.CGLIB$applicationEntityManagerFactoryBean$2(<generated>)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration$$EnhancerBySpringCGLIB$$ddb894e1$$FastClassBySpringCGLIB$$16b0ddb9.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration$$EnhancerBySpringCGLIB$$ddb894e1.applicationEntityManagerFactoryBean(<generated>)
    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.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 33 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'applicationDataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'java:comp/env/jdbc/app'; nested exception is javax.naming.NamingException: Cannot create resource  object instance due to exception in the object factory [Root exception is javax.naming.NamingException: No persistence configuration available for resource name [jdbc/app], check datasource bindings for this application]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
    ... 56 common frames omitted
Caused by: org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'java:comp/env/jdbc/app'; nested exception is javax.naming.NamingException: Cannot create resource  object instance due to exception in the object factory [Root exception is javax.naming.NamingException: No persistence configuration available for resource name [jdbc/app], check datasource bindings for this application]
    at org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup.getDataSource(JndiDataSourceLookup.java:48)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration.applicationDataSource(ApplicationDataSourceConfiguration.java:41)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration$$EnhancerBySpringCGLIB$$ddb894e1.CGLIB$applicationDataSource$0(<generated>)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration$$EnhancerBySpringCGLIB$$ddb894e1$$FastClassBySpringCGLIB$$16b0ddb9.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
    at com.sap.cloud.se.trainer.app.config.ApplicationDataSourceConfiguration$$EnhancerBySpringCGLIB$$ddb894e1.applicationDataSource(<generated>)
    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.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 57 common frames omitted
Caused by: javax.naming.NamingException: Cannot create resource  object instance due to exception in the object factory
    at com.sap.core.services.accessor.tomcat.support.DelegatingObjectFactory.getObjectInstanceFromFactory(DelegatingObjectFactory.java:109)
    at com.sap.core.services.accessor.tomcat.support.DelegatingObjectFactory.getObjectInstance(DelegatingObjectFactory.java:47)
    at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:96)
    at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:839)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:827)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:827)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:159)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:827)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:173)
    at org.apache.naming.SelectorContext.lookup(SelectorContext.java:163)
    at javax.naming.InitialContext.lookup(InitialContext.java:417)
    at org.springframework.jndi.JndiTemplate.lambda$lookup$0(JndiTemplate.java:157)
    at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:92)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:157)
    at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179)
    at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:96)
    at org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup.getDataSource(JndiDataSourceLookup.java:45)
    ... 68 common frames omitted
Caused by: javax.naming.NamingException: No persistence configuration available for resource name [jdbc/app], check datasource bindings for this application
    at com.sap.cloud.runtime.kotyo.persistence.client.PersistenceDataSourceFactory.getObjectInstance(PersistenceDataSourceFactory.java:51)
    at com.sap.core.services.accessor.tomcat.support.DelegatingObjectFactory.getObjectInstanceFromFactory(DelegatingObjectFactory.java:99)
    ... 87 common frames omitted
|

我是否没有正确配置数据源?

0 个答案:

没有答案
相关问题