Issue
I am creating two projects globalDB and GlobalWeb using spring. I want to create multiple database connections in GlobalWeb, Jdbc properties are fetched from GlobalDB project dao layer at the time of GlobalWeb initiation. When i run the global web, Am getting the following exception.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'globalWebConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.kla.it.dao.Dao com.kla.it.global.conf.GlobalWebConfig.dao; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'daoImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.jdbc.core.JdbcTemplate com.kla.it.dao.impl.DaoImpl.template; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'template' defined in class path resource [com/kla/it/database/DatabaseConfig.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.sql.DataSource]: : Error creating bean with name 'partsDs' defined in com.kla.it.global.conf.GlobalWebConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.datasource.DriverManagerDataSource]: Circular reference involving containing bean 'globalWebConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'getPartsDataSource' threw exception; nested exception is java.lang.NullPointerException; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'partsDs' defined in com.kla.it.global.conf.GlobalWebConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.datasource.DriverManagerDataSource]: Circular reference involving containing bean 'globalWebConfig' - consider declaring the factory method as static for independence from its containing instance. Factory method 'getPartsDataSource' threw exception; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:834) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:446) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:328) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4680) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5143) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:717) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:690) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:705)
GlobalDB configuration class
@Configuration
@ComponentScan(basePackages = "com.kla.it")
@PropertySource(value = {"classpath:database.properties"})
public class DatabaseConfig {
@Autowired
private Environment env;
// @Bean(name="ds")
public DataSource getDataSource(){
System.out.println("++++++++++++++++DATABASE++++++++++++++START++++++++++++");
System.out.println("Method to crate data source");
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("net.snowflake.client.jdbc.SnowflakeDriver");
ds.setUrl(env.getRequiredProperty("db.url"));
ds.setUsername(env.getRequiredProperty( "db.username"));
ds.setPassword(env.getRequiredProperty( "db.password"));
return ds;
}
@Bean(name="template")
public JdbcTemplate jdbcTemplate(DataSource ds) {
System.out.println("Jdbc template method called.");
JdbcTemplate template = new JdbcTemplate(ds);
template.setResultsMapCaseInsensitive(true);
System.out.println("++++++++++++++++DATABASE++++++++++++++END+++++++++++");
return template;
}
}
GlobalDB Dao Layer class
@Repository
@Qualifier("dao")
public class DaoImpl implements Dao{
@Autowired
JdbcTemplate template;
@Override
public Map<String, String> getConnectionsData(String appName, String env) {
List<Map<String, Object>> reportsList = new ArrayList<>();
Map<String, String> dataSourceMap = new HashMap<>();
String qry = "SELECT * FROM DB_CONFIG WHERE name = '"+appName+"' AND ev = '"+env+"'";
reportsList = template.queryForList(qry);
int count = 1;
for (Map<String, Object> map : reportsList) {
dataSourceMap.put(String.valueOf(map.get("prop")), String.valueOf(map.get("val")));
}
return dataSourceMap;
}
}
GlobalWeb Config class
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.kla.it")
@PropertySource(value = {"classpath:global.properties"})
public class GlobalWebConfig extends WebMvcConfigurerAdapter {
@Autowired(required=true)
Dao dao;
@Bean(name = "partsDs")
public DriverManagerDataSource getPartsDataSource(){
Map<String, String> dsMap = dao.getConnectionsData("parts", "dev");
DriverManagerDataSource partsDs= new DriverManagerDataSource();
partsDs.setDriverClassName(dsMap.get("driver"));
partsDs.setUrl(dsMap.get("url"));
partsDs.setUsername(dsMap.get("user"));
partsDs.setPassword(dsMap.get("password"));
return partsDs;
}
@Bean(name = "cosmosDs")
public DriverManagerDataSource getCosmosDataSource(){
Map<String, String> dsMap = dao.getConnectionsData("cosmos", "dev");
DriverManagerDataSource cosmosDs = new DriverManagerDataSource();
cosmosDs.setDriverClassName(dsMap.get("driver"));
cosmosDs.setUrl(dsMap.get("url"));
cosmosDs.setUsername(dsMap.get("user"));
cosmosDs.setPassword(dsMap.get("password"));
return cosmosDs;
}
@Bean(name = "itsDs")
public DataSource getITSDataSource(){
Map<String, String> dsMap = dao.getConnectionsData("ITSecurity", "dev");
DriverManagerDataSource itsDs= new DriverManagerDataSource();
itsDs.setDriverClassName(dsMap.get("driver"));
itsDs.setUrl(dsMap.get("url"));
itsDs.setUsername(dsMap.get("user"));
itsDs.setPassword(dsMap.get("password"));
return itsDs;
}
@Bean(name = "sfPartsDB")
public JdbcTemplate snowFlakeParts() {
System.out.println("Jdbc template method called.");
DataSource cosmosDs = getPartsDataSource();
JdbcTemplate sfPartsDB = new JdbcTemplate(cosmosDs);
sfPartsDB.setResultsMapCaseInsensitive(true);
return sfPartsDB;
}
@Bean(name = "sfCosmosDB")
public JdbcTemplate snowFlakeCosmos() {
System.out.println("Jdbc template method called.");
DataSource cosmosDs = getCosmosDataSource();
JdbcTemplate sfCosmosDB = new JdbcTemplate(cosmosDs);
sfCosmosDB.setResultsMapCaseInsensitive(true);
return sfCosmosDB;
}
//
@Bean(name = "oracleDB")
public JdbcTemplate oracleTemplate() {
DataSource itsDs = getITSDataSource();
JdbcTemplate oracleDB = new JdbcTemplate(itsDs);
oracleDB.setResultsMapCaseInsensitive(true);
return oracleDB;
}
}
Solution
Please try with below code. It works!!
1. @Qualifier to particular datasource reference(by name).
2. @Import Aggregate all the configuration classes.
@Configuration
@ComponentScan(basePackages = "com.kla.it")
@PropertySource(value = {"classpath:database.properties"})
public class DatabaseConfig {
@Autowired
private Environment env;
@Bean(name="ds")
public DataSource getDataSource(){
System.out.println("++++++++++++++++DATABASE++++++++++++++START++++++++++++");
System.out.println("Method to crate data source");
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("net.snowflake.client.jdbc.SnowflakeDriver");
ds.setUrl(env.getRequiredProperty("db.url"));
ds.setUsername(env.getRequiredProperty( "db.username"));
ds.setPassword(env.getRequiredProperty( "db.password"));
return ds;
}
@Bean(name="template")
public JdbcTemplate jdbcTemplate(@Qualifier("ds")DataSource ds) {
System.out.println("Jdbc template method called.");
JdbcTemplate template = new JdbcTemplate(ds);
template.setResultsMapCaseInsensitive(true);
System.out.println("++++++++++++++++DATABASE++++++++++++++END+++++++++++");
return template;
}
}
@Import(DatabaseConfig.class) /* add this line to aggrgate java configuration classes*/
@Configuration
@EnableWebMvc
@ComponentScanenter code here(basePackages = "com.kla.it")
@PropertySource(value = {"classpath:global.properties"})
public class GlobalWebConfig extends WebMvcConfigurerAdapter {
}
Answered By - Bala Venkatesh Koripalli