JpaPagingItemReader не может прочитать данные и перейти к следующему шагу - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть пакетный процесс Spring, который читает данные с сервера SQL и записывает в файл. Используемый мной запрос возвращает 350000 строк и занимает около 2 минут для запуска на SQL Server studio - поэтому запрос настроен для лучшей производительности.

Ниже приведен класс JobConfiguration:

@Configuration
@Slf4j
public class JobConfiguration {
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;
    private final FileProperties fileProperties;
    private JobProperties jobProperties;
    private FileUtility fileUtility;
    private CompensationDetailStatusRepository compensationDetailStatusRepository;
    private CompensationDetailsRepository compensationDetailsRepository;

    @Autowired
    public JobConfiguration(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory,
                            JobProperties jobProperties, FileProperties fileProperties
    ) {
        this.jobBuilderFactory = jobBuilderFactory;
        this.stepBuilderFactory = stepBuilderFactory;
        this.jobProperties = jobProperties;
        this.fileProperties = fileProperties;
    }

    @Bean
    public Job processExtractJob(ExtractProcessListener listener,
                                        Step processExtract,
                                        Step moveFiles
                                        ) {
        return jobBuilderFactory.get("processExtractJob")
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .start(processExtract)
                .on("COMPLETED")
                .to(moveFiles)
                .end()
                .build();
    }

    @Bean
    public Step processExtract(ItemReader<Person> PersonReader,
                                      ExtractProcessor extractProcessor,
                                      ExtractWriter extractWriter
    ) {
        return stepBuilderFactory.get("processExtract")
                .<Person, ExtractVO>chunk(50)
                .faultTolerant()
                .retryLimit(1)
                .retry(IOException.class)
                .retry(UncheckedIOException.class)
                .reader(PersonReader)
                .processor(extractProcessor)
                .writer(extractWriter)
                .build();
    }

    @Bean
    public ExtractWriter extractWriter() {
        return new ExtractWriter();
    }

    @Bean
    public ExtractProcessor extractProcessor() {
        return new ExtractProcessor();
    }

    @Bean
    public Step moveFiles() {
        return stepBuilderFactory.get("moveFiles")
                .tasklet((contribution, chunkContext) -> {
                    fileUtility.moveFiles(String.format("%s*", fileProperties.getFileNamePrefix()),
                            fileProperties.getFileStagingPath(), fileProperties.getFileTargetPath());
                    return RepeatStatus.FINISHED;
                }).build();
    }

    @Bean
    @StepScope
    public ItemReader<Person> PersonReader(EntityManagerFactory entityManagerFactory) {
        String query = "Select new com.example.Person (DTL.personId,DTL.description) FROM DETAIL DTL;";
        JpaPagingItemReader<Person> reader = new JpaPagingItemReader<>();
        reader.setQueryString(query);
        reader.setTransacted(false);
        reader.setPageSize(jobProperties.getReaderPageSize());
        reader.setEntityManagerFactory(entityManagerFactory);
        reader.setPageSize(jobProperties.getReaderPageSize());
        return reader;
    }

    @Bean
    public ExtractProcessListener jobExecutionListener() {
        return new ExtractProcessListener();
    }
}

Ниже представлен объект java (Person. java) для набора результатов базы данных:

@ToString
@AllArgsConstructor
@NoArgsConstructor
@Data
public class PersonCompensation {
    private String personId;
    private String description;
}

Когда Я запускаю пакетный процесс, я получаю следующее исключение:

2020-04-15 21:34:59.172 ERROR 11748 --- [rTaskExecutor-1] o.s.batch.core.step.AbstractStep         : Encountered an error executing step processExtract in job processExtractJob
org.springframework.batch.core.step.skip.NonSkippableReadException: Non-skippable exception during read
    at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:105) ~[spring-batch-core-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.batch...
Caused by: java.lang.NullPointerException: null
    at org.springframework.batch.item.database.JpaPagingItemReader.doReadPage(JpaPagingItemReader.java:196) ~[spring-batch-infrastructure-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.batch.item.database.AbstractPagingItemReader.doRead(AbstractPagingItemReader.java:108) ~[spring-batch-infrastructure-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.batch.item.support...
    ... 27 common frames omitted
2020-04-15 21:34:59.946  WARN 11748 --- [rTaskExecutor-1] o.s.b.f.support.DisposableBeanAdapter    : Invocation of destroy method 'close' failed on bean with name 'scopedTarget.personCompensationReader': org.springframework.batch.item.ItemStreamException: Error while closing item reader
2020-04-15 21:35:00.277 ERROR 11748 --- [rTaskExecutor-1] o.s.batch.core.job.AbstractJob           : Encountered fatal error executing job
org.springframework.batch.core.JobExecutionException: Flow execution ended unexpectedly
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:140) ~[spring-batch-core-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) ~[spring-batch-core-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.batch.core...
Caused by: org.springframework.batch.core.job.flow.FlowExecutionException: Next state not found in flow=processExtractJob for state=processExtractJob.processExtract with exit status=FAILED
    at org.springframework.batch.core.job.flow.support.SimpleFlow.nextState(SimpleFlow.java:230) ~[spring-batch-core-3.0.8.RELEASE.jar:3.0.8.RELEASE]
    at org.springframework.batch.core...
Exit Code: FAILED
Exit Desc: org.springframework.batch.core.step.skip.NonSkippableReadException: Non-skippable exception during read
    at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:105)
    at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:116)
    at org.springframework.batch...
Caused by: java.lang.NullPointerException
    at org.springframework.batch.item.database.JpaPagingItemReader.doReadPage(JpaPagingItemReader.java:196)
    at org.springframework.batch.item.database.AbstractPagingItemReader.doRead(AbstractPagingItemReader.java:108)
    at org.springframework.batch.item...
    ... 27 more

У меня есть три вопроса:

  1. Запрашивает ли весенний пакетный процесс и получает все 350000 строк одновременно и передать записи процессору кусками по 50 (размер куска)?
  2. У меня есть эта строка в коде JpaPagingItemReader<Person> reader = new JpaPagingItemReader<>();. Должен ли класс Person быть объектом Entity для того, чтобы это работало, или любой из них будет нормально работать POJO?
  3. Что может быть причиной вышеуказанного исключения?

1 Ответ

1 голос
/ 16 апреля 2020
  1. Обрабатывает ли весенний пакет все запросы и извлекает все 350000 строк одновременно и передает записи процессору по 50 (размер блока)?

Нет, он будет читать только pageSize элементов одновременно, но не все из них (в этом смысл чтения страниц). ChunkSize и PageSize - это разные параметры. Например, вы можете прочитать страницу из 100 элементов и иметь 10 блоков по 10 элементов для каждой страницы. Соответствие pageSize и chunkSize обычно дает лучшую производительность. Пожалуйста, обратитесь к Javado c.

У меня есть эта строка в коде JpaPagingItemReader reader = new JpaPagingItemReader <> () ;. Должен ли класс Person быть объектом Entity для того, чтобы это работало, или любой из них будет работать нормально POJO?

Да, в противном случае я не вижу цели использования считывателя JPA (JDB C одного будет достаточно).

Что может быть причиной вышеуказанного исключения?

У вас есть NullPointerException здесь , что означает, что диспетчер сущностей равен null. Вам нужно вызвать afterPropertiesSet на вашем ридере, чтобы убедиться, что он правильно настроен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...