Spring Boot 与 spring batch 和 jpa 的集成 [英] Spring boot integration with spring batch and jpa

查看:112
本文介绍了Spring Boot 与 spring batch 和 jpa 的集成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将 spring boot 项目与 spring 批处理和数据 jpa 项目集成.与作业和数据配置相关的所有内容都是正确的,除了将我的作业编写器结果保存在数据库中.读取文件并处理后,无法将其写入 mysql 数据库.没有错误,但也没有插入.有趣的是我的数据源已配置.因为在插入之前,我可以从数据库中获取样本记录.请帮助我解决这个问题.

I am integrating a spring boot project with a spring batch and data jpa project . All stuff related to job and data configuration is right except , persisting my job writer result in database . after I read a file and process it , i can't write it to mysql database . There is no error but no inserting too . interesting thing is my datasource is configured . because before inserting , I can fetch a sample record from database .please assist me to solve this problem.

我的 application.properties :

my application.properties :

spring.datasource.url = jdbc:mysql://localhost:3306/batchtest?  characterEncoding=UTF-8&autoReconnect=true
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

批量配置:

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;

@Bean
public ResourcelessTransactionManager transactionManager() {
    return new ResourcelessTransactionManager();
}

@Bean
public JobRepository jobRepository(ResourcelessTransactionManager transactionManager) throws Exception {
    MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean(transactionManager);
    mapJobRepositoryFactoryBean.setTransactionManager(transactionManager);
    return mapJobRepositoryFactoryBean.getObject();
}

@Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
    SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
    simpleJobLauncher.setJobRepository(jobRepository);
    return simpleJobLauncher;
}
@Bean
public FlatFileItemReader<Person> reader() {
    FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
    reader.setResource(new ClassPathResource("sample-data.csv"));
    reader.setLineMapper(new DefaultLineMapper<Person>() {{
        setLineTokenizer(new DelimitedLineTokenizer() {{
            setNames(new String[] { "firstName", "lastName" });
        }});
        setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
            setTargetType(Person.class);
        }});
    }});
    return reader;
}
@Bean
public PersonItemProcessor processor() {
    return new PersonItemProcessor();
}
@Bean
public ItemWriter<Person> writer() throws Exception {
    return new PersonWriter();
}
@Bean
public Job importUserJob() throws Exception{
    return jobBuilderFactory.get("importUserJob")
            .incrementer(new RunIdIncrementer())
            .flow(step1())
            .end()
            .build();
}
 @Bean
public Step step1() throws Exception{
    return stepBuilderFactory.get("step1")
            .<Person, Person> chunk(1)
            .reader(reader())
            .processor(processor())
            .writer(writer())
            .build();
}

道类:

public interface PersonDao extends CrudRepository<Person,Integer> {
}

作家类:

public class PersonWriter implements ItemWriter<Person> {
@Autowired
PersonDao personDao;

@Override
public void write(List<? extends Person> items) throws Exception {
    LOGGER.info("Received the information of {} students", items.size());
    for(Person person:items)
    {
        LOGGER.info(String.format("inserting for customre %s %s", person.getFirstName(), person.getLastName()));
        Person tempPerson = personDao.findOne(1);
        personDao.save(person) ;
        LOGGER.info(String.format("person id : %d",person.getId()));
    }

}

tempPerson 是一个用于测试 jpa 数据的对象.它从数据库中获取一个 id 1 的 person 对象,但下一行没有插入数据库,没有错误.只是执行该行并继续循环.

tempPerson is an object for testing the jpa data . it fetches a person object with id 1 from database but next line there is no inserting to database with no error. just executing of the line and continue the loop.

推荐答案

此问题的解决方案可能比预期更接近.您是否只是尝试更改 transactionManager bean 的名称?Spring Data JPA 默认不会使用不同的名称.

A solution to this problem may be closer than expected. Did you simply try to change the name of the transactionManager bean? With a different name it won't be used by default by Spring Data JPA.

我重现了你的问题,然后我只是从这个切换:

I reproduced your problem and then I simply switched from this:

@Bean
public ResourcelessTransactionManager transactionManager() {
    return new ResourcelessTransactionManager();
}

到此:

@Bean
public ResourcelessTransactionManager resourcelessTransactionManager() {
    return new ResourcelessTransactionManager();
}

在我看来,这解决了问题.请记住,'transactionManager' 是 Spring Data JPA 中 transactionManager 的默认 bean 名称(至少据我所知,Spring Boot 会自动配置它,除非它找到具有该名称的 Bean,如果找到,则使用找到的--并且您的数据库事务正在经历一个无资源的事务).

And in my opinion that solved the problem. Remember that 'transactionManager' is the default bean name for transactionManager in Spring Data JPA (at least as far as I understand, Spring Boot auto-configures it unless it finds a Bean with that name, and if it does, it uses the one found--and your database transactions are going through a Resourceless one).

你也可以跳过这个:

@Bean
public JobRepository jobRepository(ResourcelessTransactionManager transactionManager) throws Exception {
    return new MapJobRepositoryFactoryBean(transactionManager).getObject();
}

并直接调用 bean(只是为了更确定"Batch 使用了正确的事务管理器):

and call the bean directly (just to be 'more sure' that proper Transaction Manager is used with Batch):

@Bean
public JobRepository jobRepository() throws Exception {
    return new MapJobRepositoryFactoryBean(resourcelessTransactionManager()).getObject();
}

测试时告诉我,我希望这是主要问题:)

Let me know when you test it, and I hope that it was the main problem :)

这篇关于Spring Boot 与 spring batch 和 jpa 的集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆