0

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

robert trudel
  • 5,283
  • 17
  • 72
  • 124
  • Does this answer your question? [JpaItemWriter: no transaction is in progress](https://stackoverflow.com/questions/22509529/jpaitemwriter-no-transaction-is-in-progress) – Mahmoud Ben Hassine Dec 02 '20 at 18:38
  • not really, I have two datasource... completely different of your link – robert trudel Dec 02 '20 at 18:57
  • It's not the number of datasources that causes this issue. If this happen, it means your writer is being called outside the scope of a JPA transaction. So as mentioned in this answer: https://stackoverflow.com/a/22691112/5019386, you need to set a `JpaTransactionManager` on your step or configure Spring Batch to use your JpaTransactionManager to drive transactions. – Mahmoud Ben Hassine Dec 02 '20 at 19:00
  • See https://stackoverflow.com/questions/59511893/javax-persistence-transactionrequiredexception-no-transaction-is-in-progress/59576570#59576570. – Mahmoud Ben Hassine Dec 02 '20 at 19:03
  • your link provided is not really clear. I created two datasource, each one has a transaction manager. In both of your link, there is only one datasource and transaction. Like you can see in my Code, I have already a JpaTransactionManager for each one of my datasource – robert trudel Dec 02 '20 at 20:19
  • I see your confusion. ok you have two datasources and two transaction managers. You have set the `billingDataSource` in your `BatchConfigurer`, but which transaction manager do you think spring batch is using? – Mahmoud Ben Hassine Dec 03 '20 at 12:24
  • i think that depend... i was thinking it use the one i speficied.. but don't seem the case it's fixed with ChainedTransactionmanager... but maybed there is a better way... – robert trudel Dec 09 '20 at 16:03

0 Answers0