Spring 批处理 - org.springframework.batch.item.ReaderNotOpenException - jdbccursoritemreader

Spring batch - org.springframework.batch.item.ReaderNotOpenException - jdbccursoritemreader

我在尝试读取 Item Reader 实现中的 JdbcCursorItemReader 时收到 reader not open 异常。我检查了堆栈溢出,但无法讨论 jdbc 项目 reader。

这里是批量配置和项目reader实现的代码。仅添加了必需的代码。

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

我无法在批处理配置中将项目 reader 写为 bean,因为我需要在项目 reader 中的步骤之前调用以访问步骤执行。

如果Item reader read()函数return类型改为jdbccursorItemReader类型,在步骤reader中抛出类型异常().

让我知道我缺少什么或需要任何其他代码片段。

您正在 AllocationReaderread 方法中创建一个 JdbcCursorItemReader 实例。这是不正确的。此方法的代码应该是实际 read 操作的实现,而不是用于创建项目 reader.

I could not write Item reader as bean in batch config as i need to call before step in item reader to access step execution.

对于此用例,您可以将 reader 定义为步作用域 bean,并根据需要从作业执行上下文中注入属性。这在此处的参考文档中进行了解释:Late Binding of Job and Step Attributes。在您的情况下,reader 可以这样定义:

@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;
}

当你定义一个 reader bean 是一个 ItemStream 时,你需要使 bean 定义方法 return 至少 ItemStreamReader (或实际实现类型),以便 Spring Batch 正确地确定 bean 的范围并在步骤中适当地调用 open/update/close。否则,将不会调用 open 方法,因此您将得到 ReaderNotOpenException.