Issue
I am trying to configure two datasources which use the same azure sql username/password but different urls/databases. I am using the @Primary annotation and split up the data access layers into their own folders but only the config without @Primary gets configured.
DataSource1:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = Constants.BASE_PAKAGE,
entityManagerFactoryRef = Constants.ENTITY_MANAGER_FACTORY,
transactionManagerRef= Constants.TRANSACTION_MANAGER)
public class DataSourceConfiguration {
private Logger log = LoggerFactory.getLogger(this.getClass());
public DataSourceConfiguration(Environment environment) {
this.environment = environment;
}
private Environment environment;
@Primary
@Bean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder() {
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), new HashMap<>(), null);
}
@Primary
@Bean(name = Constants.ENTITY_MANAGER_FACTORY)
public LocalContainerEntityManagerFactoryBean sqlserverEntityManagerFactory(
EntityManagerFactoryBuilder builder) throws IllegalAccessException, InvocationTargetException, InstantiationException {
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect",environment.getProperty("sqlserver.datasource1.dialect"));
return builder
.dataSource(dataSource())
.packages(Constants.ENTITY_PATH)
.properties(properties)
.build();
}
@Primary
@Bean
public PlatformTransactionManager sqlserverTransactionManager(
final @Qualifier(Constants.ENTITY_MANAGER_FACTORY) LocalContainerEntityManagerFactoryBean sqlserverEntityManagerFactory) {
return new JpaTransactionManager(sqlserverEntityManagerFactory.getObject());
}
@Primary
@Bean
protected HikariDataSource dataSource() throws IllegalAccessException, InvocationTargetException, InstantiationException {
HikariConfig config = new HikariConfig();
config.setDriverClassName(environment.getProperty("sqlserver.datasource1.driver"));
config.setJdbcUrl(this.buildSnowflakeJDBCUrl());
config.setUsername(environment.getProperty("sqlserver.datasource1.username"));
config.setPassword(environment.getProperty("sqlserver.datasource1.password"));
HikariDataSource dataSource = new HikariDataSource(config);
return dataSource;
}
private String buildSnowflakeJDBCUrl() {
StringBuilder url = new StringBuilder();
url.append(environment.getProperty("sqlserver.datasource1.url"));
return url.toString();
}
}
and DataSource2:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = Constants.BASE_PACKAGE2,
entityManagerFactoryRef = "sqlserver2EntityManagerFactory",
transactionManagerRef= "sqlserver2TransactionManager")
public class DataSourceConfiguration2 {
private Logger log = LoggerFactory.getLogger(this.getClass());
public PhDataSourceConfiguration(Environment environment) {
this.environment = environment;
}
private Environment environment;
@Bean
public EntityManagerFactoryBuilder entityManagerFactoryBuilder() {
return new EntityManagerFactoryBuilder(new HibernateJpaVendorAdapter(), new HashMap<>(), null);
}
@Bean(name = "sqlserver2EntityManagerFactory")
public LocalContainerEntityManagerFactoryBean sqlserverEntityManagerFactory(
EntityManagerFactoryBuilder builder) throws IllegalAccessException, InvocationTargetException, InstantiationException {
HashMap<String, Object> properties = new HashMap<>();
properties.put("hibernate.dialect",environment.getProperty("sqlserver.datasource2.dialect"));
return builder
.dataSource(dataSource())
.packages(Constants.ENTITY_PATH2)
.properties(properties)
.build();
}
@Bean(name = "sqlserver2TransactionManager")
public PlatformTransactionManager sqlserverTransactionManager(
final @Qualifier("sqlserver2EntityManagerFactory") LocalContainerEntityManagerFactoryBean sqlserverEntityManagerFactory) {
return new JpaTransactionManager(sqlserverEntityManagerFactory.getObject());
}
@Bean
protected HikariDataSource dataSource() throws IllegalAccessException, InvocationTargetException, InstantiationException {
HikariConfig config = new HikariConfig();
config.setDriverClassName(environment.getProperty("sqlserver.datasource2.driver"));
config.setJdbcUrl(this.buildJDBCUrl());
config.setUsername(environment.getProperty("sqlserver.datasource2.username"));
config.setPassword(environment.getProperty("sqlserver.datasource2.password"));
HikariDataSource dataSource = new HikariDataSource(config);
return dataSource;
}
private String buildJDBCUrl() {
StringBuilder url = new StringBuilder();
url.append(environment.getProperty("sqlserver.datasource2.url"));
return url.toString();
}
}
is it an issue because they are both reading from the same user/password for azure sql? How can I get both of the configs to work?
Solution
Thank you Andrew S. Posting your suggestion as an answer to help other community members.
Some of the bean names overlap (using the method name if not specified), so the last @Bean processed would win. Try explicitly naming the beans, and @Qualifier the correct bean instance is injected where needed.
Answered By - AbhishekKhandave-MT