Unresolveable Circular reference error when configuring multiple datasources in a spring batch

Viewed 705

I'm trying to configure two datasources in my spring batch application. One for batch metadata tables, and another for the business tables.

Snippet from my application.properties file:

spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=

spring.batchdatasource.url=
spring.batchdatasource.username=
spring.batchdatasource.password=
spring.batchdatasource.driver-class-name=

My batch config file:

@Configuration
public class SpringBatchConfig extends DefaultBatchConfigurer{

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

//  @Autowired
//  private DataSource dataSource;

    @Autowired
    private PlatformTransactionManager transactionManager;


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

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


    @Override
    public JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(batchDataSource());
//  factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setTablePrefix("schema1"+ ".BATCH_");
    factory.afterPropertiesSet();
    return factory.getObject();
    }

   /* Job and step bean definitions here */

My main class is the one annotated with @EnableBatchProcessing

@SpringBootApplication
@EnableBatchProcessing
public class SpringBatchExample1Application {

    public static void main(String[] args) {
         SpringApplication.run(SampleApplication.class, args);
    }
}

I'm getting this Requested bean is currently in creation: Is there an unresolvable circular reference? when trying to configure two datasources. It works fine when using a single datasource by autowiring(refer the commented out lines of code) instead of creating multiple beans. Following is the exception snippet:

Error creating bean with name 'springBatchConfig': Unsatisfied dependency expressed through method 'setDataSource' parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'batchDatasource': Requested bean is currently in creation: Is there an unresolvable circular reference?

I looked up and found out this occurs when there's a dependency on a bean which is still not created or is being created. I just see it in the createJobRepository method where datasource is being plugged. I still face the error even if I don't have the createJobRepository method.

It seems like the requirement is for the datasource beans to be created before others. I tried using the @Order annotation, but no luck.

EDIT:

I tried the solution from @Mykhailo Skliar's Accepted answer below, and serparated the Datasource beans into a new Configuration class. Though it resolved the initial Unresolveble circular reference issue anymore, it led me to the following error:

Error creating bean with name 'springBatchConfig': Invocation of init method failed; nested exception is org.springframework.batch.core.configuration.BatchConfigurationException: java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName.

Based on this answer, I changed my url property names as follows:

spring.datasource.jdbc-url=

spring.datasource.jdbc-url=

Though it solved the jdbcUrl error, it posed another issue:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Reference to database and/or server name in 'sample-sql-server.schema1.MY_TABLE_NAME' is not supported in this version of SQL Server.

Both my data sources are Azure SQL server instances. I looked up and found it was not possible to use multiple Azure SQL databases years ago, but based on this answer it should not be the case anymore.

1 Answers

The issue is most probably because of

factory.setDataSource(batchDataSource());

You should use autowired bean here, instead of calling batchDataSource()

I would split SpringBatchConfig in two beans:

@Configuration
public class DataSourceConfig {



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

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






@Configuration
public class SpringBatchConfig extends DefaultBatchConfigurer{

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;


    @Qualifier("batchDataSource")
    @Autowired
    private DataSource batchDataSource;

    @Autowired
    private PlatformTransactionManager transactionManager;



    @Override
    public JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(batchDataSource);
    factory.setTransactionManager(transactionManager);
    factory.setTablePrefix("schema1"+ ".BATCH_");
    factory.afterPropertiesSet();
    return factory.getObject();
    }
}
Related