Spring интеграция с загрузкой с Spring партиями и jpa

Я интегрирую проект загрузки spring с проектом spring batch и data jpa. Все вещи, связанные с конфигурацией работы и данных, являются правильными, за исключением того, что мой результат записи задания в базе данных сохраняется. после того, как я прочитал файл и обработал его, я не могу записать его в базу данных mysql. Нет ошибки, но нет вставки. Интересно, настроен ли мой источник данных. потому что перед вставкой я могу получить образец записи из базы данных .please помогите мне решить эту проблему.

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();
}

Класс Dao:

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. он извлекает объект person с id 1 из базы данных, но в следующей строке нет вставки в базу данных без ошибок. просто выполняя линию и продолжая цикл.

Ответ 1

Решение этой проблемы может быть ближе, чем ожидалось. Вы просто пытались изменить имя transactionManager bean? С другим именем он по умолчанию не будет использоваться Spring Data JPA.

Я воспроизвел вашу проблему, а затем я просто переключился с этого:

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

:

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

И, на мой взгляд, это решило проблему. Помните, что "transactionManager" является именем по умолчанию bean для transactionManager в Spring Data JPA (по крайней мере, насколько я понимаю, Spring Boot автоматически настраивает его, если не находит bean с этим именем, и если он делает это, он использует найденный - и транзакции вашей базы данных проходят через Resourceless).

Вы также можете пропустить это:

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

и вызовите bean напрямую (просто для того, чтобы быть "более уверенным", что соответствующий диспетчер транзакций используется с пакетом):

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

Сообщите мне, когда вы его протестируете, и я надеюсь, что это была основная проблема:)

Ответ 2

Возможно, я пропустил его, но не вижу, где вы указываете, какой метод доступа к базе данных вы используете (JPA, Hibernate, JDBC и т.д.). Я предполагаю, что JPA, но я думаю, что ваш ItemWriter должен расширить один из поддерживающих DB ItemWriters (RepositoryItemWriter, JpaItemWriter, JdbcBatchItemWriter, HibernateItemWriter). База ItemWriter ожидает, что вы сами будете управлять транзакцией и всеми ресурсами. Вместо этого попробуйте использовать RepositoryItemWriter (или в зависимости от того, что подходит). Возможно, вам придется предоставить EntityManager и убедиться, что запись вызывается из транзакции (например, метод @Transactional).