Как узнать, является ли это последним элементом в ItemProcessor SpringBatch

#java #spring #spring-batch #itemprocessor

Вопрос:

У меня есть следующий ItemProcessor, мне нужно знать, является ли элемент последним, который отправляет читатель. Возможно ли это?

Поток-это:

  • ItemReader — считывание строк из базы данных (ожидаемые миллионы строк)
  • ItemProcessor — выполните некоторые проверки в каждой строке, отправьте в веб-сервис и выполните дополнительные проверки с ответом веб-сервиса.
  • ItemWriter — запишите в базу данных ошибки при проверке и измените статус строки.

Другим возможным решением было бы средство чтения элементов для отправки списка Line с размером NUMBER_OF_LINES_TO_CALL_WEBSERVICE , но я не смог найти примеров того, как его изменить JpaPagingItemReader .

 
    @Override
    public List<Line> process(Line line) {
        

        lineList.add(line);

        if (lineList.size() == NUMBER_OF_LINES_TO_CALL_WEBSERVICE) {

            callWs(lineList);
            
            return lineList;    // goes to ItemWriter to write the response from ws in database 
        }
        
        if( /* TODO if last line */) {      
            
            callWs(lineList);

            return lineList;
        }
        

        return null;
    }
    
    private void callWs(List<Line> lineList){
        ...
        //Get response from webservice and add info to lines
    }

    @Override
    public void afterChunk(ChunkContext chunkContext) {

        if (lineList.size() == NUMBER_OF_LINES_TO_CALL_WEBSERVICE) {
            lineList.clear();
        }

    }
    
 

Читатель-это JpaPagingItemReader :

 
    @Bean
    @StepScope
    public JpaPagingItemReader<Line> itemReader(@Qualifier("EntityManagerFactory") EntityManagerFactory entityManagerFactory) {


        String queryStr = "select l from Line l" ;

        return new JpaPagingItemReaderBuilder<Linha>()
                .name("lineReader")
                .entityManagerFactory(entityManagerFactory)
                .queryString(queryStr)
                .pageSize(PAGE_SIZE)
                .build();
    }
 

Комментарии:

1. Зачем тебе это нужно? Можете ли вы описать, чего вы пытаетесь достичь, не обращаясь к весенней партии? Каков ввод/вывод вашего шага/задания? Есть способ сделать это, но это зависит от ответов на эти вопросы.

2. Я хочу сгруппировать строки в списке из 100 элементов для отправки в веб-сервис, и когда последний элемент отправляется в процессор, остальные строки отправляются в веб-сервис.

Ответ №1:

Я хочу сгруппировать строки в списке из 100 элементов для отправки в веб-сервис, и когда последний элемент отправляется в процессор, остальные строки отправляются в веб-сервис.

Вы можете использовать шаг, ориентированный на фрагмент, с размером фрагмента 100. Этот шаг выполнит буферизацию за вас, и первый пункт процесса, в котором у вас будет доступ к списку элементов, находится в разделе ItemWriteListener#beforeWrite(List items) . Таким образом, вы можете либо использовать этот прослушиватель для выполнения вызова веб-службы, либо сделать это ItemWriter самостоятельно (если это единственная write операция, которую вам нужно выполнить).

Как только у вас будет список товаров, вы сможете делать с ним все, что захотите (т. Е. проверять последний товар, фильтровать первые 99 товаров и отправлять их в веб-службу и т. Д.).

Комментарии:

1. Это не единственная write операция. То ItemWriter запишет ошибки в базу данных. Может быть, лучшим подходом было бы изменить ItemReader отправку списка из 100 элементов, вы согласны? Но при таком подходе мне нужна помощь , чтобы изменить ItemReader , может быть, я смогу создать конкретный вопрос для этого.

2. В этом случае вы можете использовать ItemWriteListener#beforeWrite для выполнения вызова веб-службы и ItemWriter для записи в базу данных. Я не вижу необходимости изменять читателя, вы должны использовать фрагментацию/буферизацию элементов, предоставляемых пошаговой реализацией.

3. Спасибо, я об этом не знал ItemWriteListener . Такой подход выглядит хорошо