Question
How can I resolve the exception related to configuring multiple DataSources in Spring Batch?
@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
}
...
}
Answer
Configuring multiple DataSources in Spring Batch requires specific steps to avoid conflicts with the default BatchConfigurer. When you declare more than one DataSource, you must customize your batch configuration to avoid runtime exceptions regarding datasource conflicts.
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Primary
@Bean(name = "baseDatasource")
public DataSource dataSource() { /* datasource 1 implementation */ }
@Bean(name = "secondaryDataSource")
public DataSource secondaryDataSource() { /* datasource 2 implementation */ }
@Bean
public JobRepository jobRepository() throws Exception {
return new JobRepositoryFactoryBean(dataSource()).getObject();
}
@Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
Causes
- Spring Batch's default configuration assumes a single DataSource for job repository and execution context.
- The exception 'To use the default BatchConfigurer the context must contain no more than one DataSource, found 2' indicates that the application context is detecting more than one DataSource bean.
Solutions
- Implement a custom BatchConfigurer that can handle multiple DataSources.
- Ensure that your job repository is explicitly configured to use the correct DataSource.
Common Mistakes
Mistake: Not defining a custom BatchConfigurer when multiple datasources are used.
Solution: Create a class that implements BatchConfigurer and overrides createJobRepository to point to the desired DataSource.
Mistake: Using @Primary on both DataSources.
Solution: Only use @Primary on the DataSource you want to default to, typically the main one used in most batch operations.
Mistake: Assuming XML configuration allows multiple datasources without additional configuration.
Solution: When migrating from XML to Java Config, ensure all necessary configurations are revised accordingly.
Helpers
- Spring Batch
- multiple DataSources
- BatchConfigurer
- Spring Boot
- DataSource configuration