In a spring boot app, I use spring batch. I have two datasource.
For the reader, I use JpaPagingItemReader
My batch config class
@Configuratoin
@EnableBatchProcessing
public class ScoreConfig{
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
@Qualifier("billingEntityManagerFactory")
EntityManagerFactory billingEmf;
@Autowired
@Qualifier("crEntityManagerFactory")
EntityManagerFactory crEmf;
@Bean
BatchConfigurer configurer(@Qualifier("billingDataSource") DataSource dataSource){
return new DefaultBatchConfigurer(dataSource);
}
@Bean
public JpaPagingItemReader<PR> billingJpaPagingItemReader(){
return new JpaPagingItemReaderBuilder<PR>()
.name("prItemReader")
.entityManagerFactory(billingEmf)
.queryString("...")
.pageSize(10)
.build();
}
@Bean
public ItemProcessor<PR,CR> processor(){
return new ScoreProcessor();
}
@Bean
public JpaItemWriter writer(){
JpaItemWriter writer = new JpaItemWriter();
writer.setEntityManagerFactory(crEmf);
return writer;
}
@Bean
public Job scoreJob(){
return jobBuilderFactory
.get("scoreJob")
.start(scoreStep())
.build();
}
@Bean
public Step scoreStep(){
return stepBuilderFactory
.get("scoreStep")
.<PR, CS>chunk(1)
.reader(billingJpaPagingItemReader())
.processor())
.writer(writer())
.build();
}
}
My config class for my writer datasource
@Configuration
@enableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="crEntityManagerFactory",
transactionManagerRef="crTransactionManager",
basePackage="com.cnn.cs.domain.repository.cr")
public class CrDatasourceConfig{
@Bean(name="crDataSourceProperties")
@ConfigurationProperties("cr.datasource")
public DataSourceProperties crDataSourceProperties(){
return new DataSourceProperties();
}
@Bean(name="crDataSource")
@ConfigurationProperties("cr.datasource.configuration")
public DataSource crDatasource(){
return crDataSourceProperties().initializeDataSourceBuilder()
.type(HikariDataSource.class).build();
}
@Bean(name="crEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean crEntityManagerFactory(EntityManagerFactoryBuilder builder){
return builder
.dataSource(crDataSource())
.package(Cr.class)
.build();
}
@Bean(name="crTransactionManager")
public PlatformTransactionManager crTransactionManager(@Qualifier("crEntityManagerFactory") LocalContainerEntityManagerFactoryBean crEntityManagerFactory){
return new JpaTransactionManager(crEntityManagerFactory.getObject());
}
}
When I run application with a dummy writer, job is completed without issue.
With my writer, I get javax.persistence.TransactionRequiredException: no transaction is in progress
Edit solution are to put both transaction in a ChainedTransactionmanager