Issue
I have two databases I need instances of at the same time, they are running on a oracle weblogic server rather than locally. In a configurator class, I have specified the sources and tested the connection and both DBs pull data properly. (When used one at a time, or with one as @Primary)
@Configuration
public class appDatabaseConfiguration {
@Bean
@Primary
public DataSource dataSourceA() throws Exception{
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
JndiTemplate corpdwJndiTemplate = new JndiTemplate();
return dataSourceLookup.getDataSource("<DBAProperties>");
}
@Bean
public DataSource dataSourceB() throws Exception{
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
JndiTemplate jndiTemplate = new JndiTemplate();
return dataSourceLookup.getDataSource("<DBBProperties>");
}
}
However, I am unable to use @Qualifier to tell the instantiation which bean in the configuration to select-
@Service
public class DaoImpl implements Dao{
@Autowired
@Qualifier("dataSourceA")
private JdbcTemplate dataSourceA;
@Autowired
@Qualifier("dataSourceB")
private JdbcTemplate dataSourceB;
public String getData() {
resultsA = dataSourceA.queryForObject("SELECT COUNT(*) FROM TABLE", String.class);
resultsB = dataSourceB.queryForObject("SELECT COUNT(*) FROM TABLE", String.class);
return resultsA + resultsB;
}
}
When @Qualifier is not used: DataSourceA Query will succeed, but DataSourceB will fail (Table or View doesn't exist error)- because it is pulling the @Primary bean for both instantiations
When @Qualifier is used: Application errors with-
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type
'org.springframework.jdbc.core.JdbcTemplate' available: expected at least 1 bean which
qualifies as autowire candidate. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=dataSourceA)}
I have tried adding specific names to the bean like @Bean("dataSourceA"), @Bean(name="dataSourceB") rather than relying on the function name and several other syntax changes but no results. Does anyone have some insight here?
Note: Even when one datasource bean is commented out, and the other has only a name and not @primary it still throws the same autowire bean error, so I don't believe that the annotation is functioning properly in my project (or I'm using it wrong).
Solution
You'll have to create two JdbcTemplates
each configured with a different datasource and autowire with the qualifier of the template, for example with
@Bean
@Primary
public JdbcTemplate jdbcTemp1(@Qualifier("dataSourceA") DataSource ds) {
return new JdbcTemplate(ds);
}
@Bean
public JdbcTemplate jdbcTemp2(@Qualifier("dataSourceB") DataSource ds) {
return new JdbcTemplate(ds);
}
...
@Autowired
@Qualifier("jdbcTemp2")
private JdbcTemplate jdbcTemplate;
Answered By - Kayaman
Answer Checked By - David Marino (JavaFixing Volunteer)