#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
.