Home > Software design >  multiple data source in spring boot - jdbcTemplate is null
multiple data source in spring boot - jdbcTemplate is null

Time:10-22

I am using multiple data sources in my spring boot project as,

application.properties

#first DB
integration.datasource.jdbc-url=jdbc:sqlserver://localhost:port1/my_sample_schema1
integration.datasource.username=username
integration.datasource.password=password
integration.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
integration.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect
integration.jpa.show-sql=true


#second DB
spring.datasource.jdbc-url=jdbc:sqlserver://localhost:port2/my_sample_schema2
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.platform=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.show-sql=true 

DBConfig.java

@Configuration
public class DBConfig {

    
      
    @Primary
    @Bean(name = "integrationDataSource")
    @ConfigurationProperties(prefix = "integration.datasource")
    public DataSource integrationDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "mainDataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource mainDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Autowired
    @Bean(name = "integrationJdbcTemplate")
    public JdbcTemplate integrationJdbcTemplate(@Qualifier("integrationDataSource") DataSource integrationDataSource) {
        return new JdbcTemplate(integrationDataSource);
    }

    @Bean(name ="mainJdbcTemplate")
    @Autowired
    public JdbcTemplate mainJdbcTemplate(@Qualifier("mainDataSource") DataSource mainDataSource) {
        return new JdbcTemplate(mainDataSource);
    }
}

SampleClass.java

@Slf4j
@Component
public class SampleClass{

    @Autowired
    private  JdbcTemplate mainJdbcTemplate;
    
    @Autowired
    @Qualifier("integrationJdbcTemplate")
    private static JdbcTemplate integrationTemplate;
    
    public static final String SELECT_QUERY = "select * from tableA";

    public List<SampleDto> getDBData(SampleDto fileData) {
        List<SampleDto> data = null;
        try {
            data = integrationTemplate.query(
                    SampleClass.SELECT_QUERY, new Object[] { param1, param2 },
                    new SampleDataMapper());
        } catch (DataAccessException e) {
            log.error(e.getMessage(), e);
        }
        return data;
    }

}

In the SampleClass.java am getting integrationTemplate as null . Why is this so? mainJdbcTemplate is working. But integrationTemplate is getting as null and not able to excute the query.

CodePudding user response:

The issue is that you have a static field with @Autowired

With @Autowired fields are injected right after the construction of a bean, before any config methods are invoked. Read here for more information about Ioc and Bean injection.

Remove the static:

@Autowired
@Qualifier("integrationJdbcTemplate")
private JdbcTemplate integrationTemplate;

Of course, you can do this but it's not recommended:

private static JdbcTemplate integrationTemplate;

@Autowired
public void setIntegrationJdbcTemplate(JdbcTemplate integrationTemplate){
    SampleClass.integrationTemplate = integrationTemplate;
}

Autowiring by Name

If you use the exact same name as the one that you used for the bean initialization you don't need to put the @Qualifier, just use as:

@Autowired
private JdbcTemplate integrationJdbcTemplate;

And that's because Spring knows which bean to inject. If you have more beans of the same type then it will throw NoUniqueBeanDefinitionException then you define it with the @Qualifier.

I would also suggest marking your fields as final, just for good practices.

  • Related