I am working on my spring boot application and running with embedded tomcat 8.x. I am trying to configure three different oracle data sources using JNDI and followed this link. Below are my different files:
application-dev.properties
spring.oracle.datasource.oracleDS1.jndi-name=jdbc/oracleDS1
spring.oracle.datasource.oracleDS2.jndi-name=jdbc/oracleDS2
spring.oracle.datasource.oracleDS3.jndi-name=jdbc/oracleDS3
OracleDataSourceConfiguration
package com.adp.orbis.requesttracker.orbisrequesttracker;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
@Configuration
public class OracleDataSourceConfiguration {
@Value("${spring.oracle.datasource.oracleDS1.jndi-name}")
private String oracleDS1;
@Value("${spring.oracle.datasource.oracleDS2.jndi-name}")
private String oracleDS2;
@Value("${spring.oracle.datasource.oracleDS3.jndi-name}")
private String oracleDS3;
@Bean(name="dataSource1", destroyMethod = "")
@Profile("dev")
@Primary
public DataSource evolutionDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource(oracleDS1);
}
@Bean(name="dataSource2", destroyMethod = "")
@Profile("dev")
@Primary
public DataSource orbisQueryOnlyDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource(oracleDS2);
}
@Bean(name="dataSource3", destroyMethod = "")
@Profile("dev")
public DataSource orbisExportDataSource() {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource(oracleDS3);
}
}
TomcatEmbeddedServletContainerFactory
@Bean
public TomcatEmbeddedServletContainerFactory tomcatFactory() {
return new TomcatEmbeddedServletContainerFactory() {
@Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
tomcat.enableNaming();
return super.getTomcatEmbeddedServletContainer(tomcat);
}
@Override
protected void postProcessContext(Context context) {
ContextResource oracleDS1JNDIResource = new ContextResource();
oracleDS1JNDIResource.setName("jdbc/oracleDS1");
oracleDS1JNDIResource.setType(DataSource.class.getName());
oracleDS1JNDIResource.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver");
oracleDS1JNDIResource.setProperty("url", "jdbc:oracle:thin:@localhost:1521/mydbservice1");
oracleDS1JNDIResource.setProperty("username", "db-user-name");
oracleDS1JNDIResource.setProperty("password", "db-user-pass");
oracleDS1JNDIResource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
context.getNamingResources().addResource(oracleDS1JNDIResource);
ContextResource oracleDS2JNDIResource = new ContextResource();
oracleDS2JNDIResource.setName("jdbc/oracleDS2");
oracleDS2JNDIResource.setType(DataSource.class.getName());
oracleDS2JNDIResource.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver");
oracleDS2JNDIResource.setProperty("url", "jdbc:oracle:thin:@localhost:1521/mydbservice2");
oracleDS2JNDIResource.setProperty("username", "db-user-name");
oracleDS2JNDIResource.setProperty("password", "db-user-pass");
oracleDS2JNDIResource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
context.getNamingResources().addResource(oracleDS2JNDIResource);
ContextResource oracleDS3JNDIResource = new ContextResource();
oracleDS3JNDIResource.setName("jdbc/oracleDS3");
oracleDS3JNDIResource.setType(DataSource.class.getName());
oracleDS3JNDIResource.setProperty("driverClassName", "oracle.jdbc.driver.OracleDriver");
oracleDS3JNDIResource.setProperty("url", "jdbc:oracle:thin:@localhost:1521/mydbservice3");
oracleDS3JNDIResource.setProperty("username", "db-user-name");
oracleDS3JNDIResource.setProperty("password", "db-user-pass");
oracleDS3JNDIResource.setProperty("factory", "org.apache.tomcat.jdbc.pool.DataSourceFactory");
context.getNamingResources().addResource(oracleDS3JNDIResource);
}
};
}
But when I run this spring boot application, it throws below exception. Could you please help me what I am missing here? I tried adding @Primary with all DataSource bean. But no luck.
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected single matching bean but found 3: dataSource1,dataSource2,dataSource3
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected single matching bean but found 3: dataSource1,dataSource2,dataSource3
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1092) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer.init(DataSourceInitializer.java:77) ~[spring-boot-autoconfigure-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:311) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:134) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 38 common frames omitted