Весенняя партия — организация.весенняя работа.партия.товар.Исключение ReaderNotOpenException — jdbccursoritemreader

#spring-boot #spring-batch #spring-jdbc #itemrenderer

Вопрос:

Я получаю исключение «Читатель не открыт» при попытке прочитать JdbcCursorItemReader в реализации средства чтения элементов. Я проверил переполнение стека, но не смог получить обсуждение в программе чтения элементов jdbc.

Вот код реализации пакетной конфигурации и считывателя элементов. Добавлен только необходимый код.

     public class BatchConfig extends DefaultBatchConfigurer {
@Bean
public ItemReader<Allocation> allocationReader() {
return new AllocationReader(dataSource);
}
@Bean
public Step step() {
return stepBuilderFactory.get("step").<Allocation, Allocation>chunk (1).reader(allocationReader()).processor(allocationProcessor()).writer(allocationWriter()).build();
}
}




    public class AllocationReader implements ItemReader<Allocation> {
private DataSource ds;
private string block;
public AllocationReader(DataSource ds) {
this.ds = ds;
}
@BeforeStep
public void readStep(StepExecution StepExecution) {
this.stepExecution = StepExecution;
block = StepExecution.getJobExecution().get ExecutionContext().get("blocks");
}
@Override
public Allocation read() {
JdbcCursorItemReader<Allocation> reader = new JdbcCursorItemReader<Allocation>();
reader.setSql("select * from blocks where block_ref =   block);
reader.setDataSource(this.ds);
reader.setRowMapper(new AllocationMapper());
return reader.read();
}}
 

Я не смог записать средство чтения элементов в качестве компонента в пакетной конфигурации, так как мне нужно позвонить перед шагом в средство чтения элементов, чтобы получить доступ к stepexecution.

Если тип возвращаемого значения функции чтения элементов read() изменен на тип JdbcCursorItemReader, это вызовет исключение типа в Step reader() .

Дайте мне знать, что я упускаю, или требуется любой другой фрагмент кода .

Ответ №1:

Вы создаете JdbcCursorItemReader экземпляр в read методе AllocationReader . Это неверно. Код этого метода должен быть реализацией фактической read операции, а не для создания считывателя элементов.

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

В этом случае использования вы можете определить средство чтения как компонент с областью действия и при необходимости ввести атрибуты из контекста выполнения задания. Это объясняется в справочной документации здесь: Поздняя привязка атрибутов задания и шага. В вашем случае читатель может быть определен следующим образом:

 @Bean
@StepScoped
public JdbcCursorItemReader<Allocation> itemReader(@Value("#{jobExecutionContext['block']}") String block) {
   // use "block" as needed to define the reader
   JdbcCursorItemReader<Allocation> reader = new JdbcCursorItemReader<Allocation>();
   reader.setSql("select * from blocks where block_ref = "   block);
   reader.setDataSource(this.ds);
   reader.setRowMapper(new AllocationMapper());
   return reader;
}
 

Когда вы определяете компонент чтения элементов , который является ItemStream компонентом, вам необходимо, чтобы метод определения компонента возвращал по крайней мере ItemStreamReader (или фактический тип реализации), чтобы пакет Spring правильно определял область компонента и вызывал open/update/close соответствующие вызовы во время шага. В противном случае open метод не будет вызван, и, следовательно, вы получите это ReaderNotOpenException .