Search code examples
javaspringdatasourcespring-batch

Use of multiple DataSources in Spring Batch


I am trying to configure a couple of datasources within Spring Batch. On startup, Spring Batch is throwing the following exception:

To use the default BatchConfigurer the context must contain no more thanone DataSource, found 2

Snippet from Batch Configuration

@Configuration
@EnableBatchProcessing 
public class BatchJobConfiguration {

    @Primary
    @Bean(name = "baseDatasource")
    public DataSource dataSource() {
         // first datasource definition here
    }
    @Bean(name = "secondaryDataSource")
    public DataSource dataSource2() {
         // second datasource definition here
    }
    ...
}

Not sure why I am seeing this exception, because I have seen some xml based configuration for Spring batch that declare multiple datasources. I am using Spring Batch core version 3.0.1.RELEASE with Spring Boot version 1.1.5.RELEASE. Any help would be greatly appreciated.


Solution

  • AbstractBatchConfiguration tries to lookup BatchConfigurer in container first, if it is not found then tries to create it itself - this is where IllegalStateException is thrown where there is more than one DataSource bean in container.

    The approach to solving the problem is to prevent from creation the DefaultBatchConfigurer bean in AbstractBatchConfiguration. To do it we hint to create DefaultBatchConfigurer by Spring container using @Component annotation:

    The configuration class where @EnableBatchProcessing is placed we can annotate with @ComponentScan that scan the package that contains the empty class that is derived from DefaultBatchConfigurer:

    package batch_config;
    ...
    @EnableBatchProcessing
    @ComponentScan(basePackageClasses = MyBatchConfigurer.class)
    public class MyBatchConfig {
        ...
    }
    

    the full code of that empty derived class is here:

    package batch_config.components;
    import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer;
    import org.springframework.stereotype.Component;
    @Component
    public class MyBatchConfigurer extends DefaultBatchConfigurer {
    }
    

    In this configuration the @Primary annotation works for DataSource bean as in the example below:

    @Configuration
    public class BatchTestDatabaseConfig {
        @Bean
        @Primary
        public DataSource dataSource()
        {
            return .........;
        }
    }
    

    This works for the Spring Batch version 3.0.3.RELEASE

    The simplest solution to make @Primary annotation on DataSource work might be just adding @ComponentScan(basePackageClasses = DefaultBatchConfigurer.class) along with @EnableBatchProcessing annotation:

    @Configuration
    @EnableBatchProcessing
    @ComponentScan(basePackageClasses = DefaultBatchConfigurer.class)
    public class MyBatchConfig {