Search code examples
spring-bootspring-mvcspring-batchspring-transactions

TransactionManager to support Spring Batch and Rest Api


Have to use Rest controller to trigger failed Batch Jobs. The Scheduled Jobs are working perfectly using HibernateTransactionManager, but application throws the error when trigger the job using RestApi

ERROR : EntityManagerHolder cannot be cast to class org.springframework.orm.hibernate5.SessionHolder (org.springframework.orm.jpa.EntityManagerHolder and org.springframework.orm.hibernate5.SessionHolder are in unnamed module of loader 'app')

Below is the code snippet

@Configuration
@EnableBatchProcessing
@RequiredArgsConstructor
@Slf4j
public class EodBatchConfig extends DefaultBatchConfigurer {
private final SessionFactory sessionFactory;

    @Override
    public void setDataSource(DataSource dataSource) {
        //This BatchConfigurer ignores any DataSource
    }

    @Override
    public HibernateTransactionManager getTransactionManager() {
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory);
        return txManager;
    }
......
}

Contrller, where jobService.rerunJob calls the jobLauncher.run

 @RequestMapping(value = "/rerun", method = RequestMethod.POST)
    public BatchStatus rerunJob(@RequestParam(value = "name") String name, @RequestParam(value = "daye") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date){
        return jobService.rerunJob(name,date);
    }

jobLauncher.run(job, jobParameters) 

How can I define the TransactionManager which supports the both Spring Batch and RestController?


Solution

  • In the code you shared, EodBatchConfig creates a new transaction manager. If you want to use the transaction manager from the application context in your batch configuration, you can autowire it in EodBatchConfig and use it to configure your batch infrastructure:

    @Configuration
    @EnableBatchProcessing
    @RequiredArgsConstructor
    @Slf4j
    public class EodBatchConfig extends DefaultBatchConfigurer {
        
        @Autowired
        private HibernateTransactionManager txManager;
    
        @Override
        public HibernateTransactionManager getTransactionManager() {
            return txManager;
        }
    
        // ..
    }
    

    The autowired transaction manager would be the one configured in your Spring application context and used in different parts of the application.