I am developing a Spring Boot application that uses Spring Data JPA and will need to connect to two different databases and I've run into an issue. When the application starts up it's throwing an exception basically stating that it doesn't know which datasource to use. Here is a snippet of my configuration class. The database properties(e.g. url, username, password) are defined in the application.properties file.
@Configuration
@ComponentScan(basePackages = {"com.test"})
@EnableJpaRepositories(basePackages = {"com.test.jpa.repository"})
@EnableAutoConfiguration
@EnableTransactionManagement
public class AppConfig {
@Bean(name = "dataSource1")
DataSource dataSource1(@Value("${db1.driverClassName}") String db1DriverClassName, @Value("${db1.url}") String db1Url, @Value("${db1.username}") String db1Username, @Value("${db1.password}") String db1Password) {
DataSource dataSource = new DataSource();
dataSource.setDriverClassName(db1DriverClassName);
dataSource.setUrl(db1Url);
dataSource.setUsername(db1Username);
dataSource.setPassword(db1Password);
return dataSource;
}
@Bean(name = "dataSource2")
DataSource dataSource2(@Value("${db2.driverClassName}") String db2DriverClassName, @Value("${db2.url}") String db2Url, @Value("${db2.username}") String db2Username, @Value("${db2.password}") String db2Password) {
DataSource dataSource = new DataSource();
dataSource.setDriverClassName(db2DriverClassName);
dataSource.setUrl(db2Url);
dataSource.setUsername(db2Username);
dataSource.setPassword(db2Password);
return dataSource;
}
@Bean(name = "jpaVendorAdapter")
HibernateJpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setDatabase(Database.ORACLE);
jpaVendorAdapter.setShowSql(false);
jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.Oracle10gDialect");
return jpaVendorAdapter;
}
@Bean(name = "entityManagerFactory")
@Autowired
LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("dataSource1") DataSource dataSource, HibernateJpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);
entityManagerFactory.setPersistenceXmlLocation("classpath:persistence.xml");
entityManagerFactory.setPersistenceUnitName("springdatajpa");
entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter);
return entityManagerFactory;
}
@Bean(name = "transactionManager")
JpaTransactionManager transactionManager(LocalContainerEntityManagerFactoryBean entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory.getObject());
return transactionManager;
}
Here is the exception that is being thrown:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.dataSource; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: dataSource1,dataSource2
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:909)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:898)
at com.wth.service.logging.Application.main(Application.java:11)
I have the entityManagerFactory
method annotated with the @Autowired
annotation and the dataSource
parameter preceded with the @Qualifier("dataSource1")
annotation so this should work. I've done this before in other Spring applications and haven't had any issues. This is the first time I've come across this exception.
Does anyone have any ideas/thoughts as to what could be causing this?
Thanks, Chris