Java – jpaitemwriter: no transaction is in progress

I want to use jpaitemwriter to batch persist entities But when I use the following code to insist, I am told:

Hibernate: 
    select
        nextval ('hibernate_sequence')
[] 2014-03-19 15:46:02,237 ERROR : TransactionrequiredException: no transaction is in progress

How to enable the following transactions:

@Bean
public ItemWriter<T> writer() {
    JpaItemWriter<T> itemWriter = new JpaItemWriter<>();
    itemWriter.setEntityManagerFactory(emf);
}

@Configuration
@EnableTransactionManagement
@EnableBatchProcessing 
class Config{ {
     @Bean
    public LocalContainerEntityManagerfactorybean emf() {
        LocalContainerEntityManagerfactorybean emf = new LocalContainerEntityManagerfactorybean();
        emf.setDataSource(dataSource());
        emf.setPackagesToScan("my.package");
        emf.setJpaVendorAdapter(jpaAdapter());
        emf.setJpaProperties(jpaProterties());
        return emf;
}

Edit:

@Bean
public Job airlineJob(JobBuilderFactory jobs,Step step) {
    return jobs.get("job")
            .start(step)
            .build();
}

//Reader is a `FlatFileItemReader`,writer is `CustomItemWriter`.
@Bean
public Step step(StepBuilderFactory steps,MultiResourceItemReader<T> rea,ItemProcessor<T,T> pro,ItemWriter<T> wr) {
    return steps.get("step")
            .reader(rea)
            .processor(proc)
            .writer(wr)
            .build();
}

//use same datasource and tx manager as in the full web application
@Bean
public JobLauncher launcher(TransactionManager tx,DataSource ds) throws Exception {
    SimpleJobLauncher launcher = new SimpleJobLauncher();

    JobRepositoryfactorybean factory = new JobRepositoryfactorybean();
    factory.setDataSource(ds);
    factory.setTransactionManager(tx);

    jobLauncher.setJobRepository(factory.getJobRepository());
    return launcher;
}

Edit 2 as a reply to @ Haim:

@Bean
    public JpaItemWriter<T> jpaItemWriter(EntityManagerFactory emf) {
        JpaItemWriter<T> writer = new JpaItemWriter<T>();
        writer.setEntityManagerFactory(emf);
        return writer;
    }

Solution

I agree with Michael Minella that the spring batch job repository does not like to share its transaction manager with others The logic is simple. If you share the job transaction manager with the step transaction manager when the step fails, it will roll back the step and write the data to the job repository This means that you will not retain the data to restart the job

Delete @ enabletransactionmanagement to prevent you from using it only for other transaction managers defined by @ transactional above

@Bean
@Qualifier("jpaTrx")
public PlatformTransactionManager jpaTransactionManager() {
       return new JpaTransactionManager(emf());
}

To set up the transaction manager as your

@Autowired
@Qualifier("jpaTrx")
PlatformTransactionManager jpaTransactionManager

 //Reader is a FlatFileItemReader,writer is CustomItemWriter.
    @Bean
    public Step step(StepBuilderFactory steps,ItemWriter<T> wr) {
        return steps.get("step")
                //attach tx manager
                .transactionManager(jpaTransactionManager)
                .reader(rea)
                .processor(proc)
                .writer(wr)
                .build();
    }
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>