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.
With the xml one you have to be explicit in which datasource Spring Batch uses. If you don't declare it explicitly with Java based configuration it will try to detect the datasource to work, which will only work in case a single datasource is detected. YOu could try annotating the one to use for Batch with @Primary .
To make a spring boot application that can communicate with more than one database you need to define some configuration to let spring boot when to execute each source.
You must provide your own BatchConfigurer. Spring does not want to make that decision for you
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Bean
BatchConfigurer configurer(@Qualifier("batchDataSource") DataSource dataSource){
return new DefaultBatchConfigurer(dataSource);
}
...
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 {
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With