6

I am working on REST-service (with Spring boot), which runs batch job. I want Batch to work only with embedded datasource (to store metadata), while default datasource (Postgres in my case) will be used to store buisness entities.

The problem is that Batch tries to create metadata tables (like batch_job_execution, batch_job_instance, etc.) in default datasource at startup.

Here is the sample configuration, which reproduces the problem:

BatchConfiguration

@Configuration
@EnableBatchProcessing
public class BatchConfiguration extends DefaultBatchConfigurer {

    @Override
    @Autowired
    public void setDataSource(@Qualifier("batchDataSource") DataSource dataSource) {
        super.setDataSource(dataSource);
    }
}

DataSourceConfiguration

@Configuration
public class DataSourceConfiguration {
    @Bean
    @Primary
    public DataSource DataSource() {
        final SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriverClass(org.postgresql.Driver.class);
        dataSource.setUrl("jdbc:postgresql://localhost:5432/test_batch");
        dataSource.setUsername("user");
        dataSource.setPassword("password");

        return dataSource;
    }

    @Bean(name = "batchDataSource")
    public DataSource batchDataSource() {
        return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
    }
}

With this configuration I am getting batch tables in Postgres when microservice started, though aftewards, it seems, that embeded datasource is used, because I am getting "Table not found" error for H2 when trying to launch a job.

So how should I properly write configuration to make Batch work only with embedded datasource? I don't want any metadata (even empty tables) in main datasource.

UPDATE:

As Michael Minella said, one more bean should be added:

@Configuration
@EnableBatchProcessing
public class BatchConfiguration extends DefaultBatchConfigurer {

    @Override
    @Autowired
    public void setDataSource(@Qualifier("batchDataSource") DataSource dataSource) {
        super.setDataSource(dataSource);
    }

    @Bean
    public BatchDatabaseInitializer   batchDatabaseInitializer(@Qualifier("batchDataSource") DataSource dataSource, ResourceLoader resourceLoader){
        BatchDatabaseInitializer batchDatabaseInitializer = new     BatchDatabaseInitializer(dataSource, resourceLoader, new BatchProperties());
        return batchDatabaseInitializer;
    }
}
  • you will have to configure two different datasources. Spring boot will auto configure one for you after reading the data resource info from your properties/yml prefixed with 'spring.datasource'. This datasource will be used for storing Spring Batch meta tables. The second datasource, which you will have to create on your own can be used as your default datasource – Amit Phaltankar Apr 27 '17 at 10:40
  • Why you think 'spring.datasource' properties will affect only batch-related datasource? Could you please give an example how you see it? – Mikhail Gordienko Apr 27 '17 at 11:37

1 Answers1

5

Using Spring Boot the DataSource that is used by the BatchDataSourceInitializer is, unfortunately, not related to the BatchConfigurer. It just grabs the default DataSource in the context. If you configure your own BatchDataSourceInitializer, the Boot one won't kick in and you can define which DataSource is used directly.

Michael Minella
  • 20,843
  • 4
  • 55
  • 67
  • Btw could you please also explain why it is important to make configuration extends `DefaultBatchConfigurer` class? I've tried to put configurer as a regular bean, but in that case it wasn't used. – Mikhail Gordienko Apr 28 '17 at 09:10
  • 1
    It doesn't need to extend `DefaultBatchConfigurer`, but if you don't, you need to finish implementing the `BatchConfigurer` interface which is more work than is probably necessary. – Michael Minella Apr 28 '17 at 14:09
  • @MichaelMinella What if I do not have any Primary datasource. In my case I got 3 datasources with the processor and writer accessing all 3. Could you please check https://stackoverflow.com/questions/67651106/spring-batch-set-data-source-when-having-3-datasources-without-any-primary when you got some time – Kevin Joymungol May 23 '21 at 11:10