Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Batch doesn't use custom datasource to create tables

Tags:

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;
    }
}
like image 302
Mikhail Gordienko Avatar asked Apr 27 '17 10:04

Mikhail Gordienko


1 Answers

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.

like image 115
Michael Minella Avatar answered Oct 13 '22 22:10

Michael Minella