微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决Spring 批处理 - org.springframework.batch.item.ReaderNotOpenException - jdbccursoritemreader

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

这里是Batch config和Item 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();
}}

我无法在批处理配置中将 Item reader 作为 bean 编写,因为我需要在 step in item reader 之前调用以访问 stepexecution。

如果 Item reader read() 函数返回类型更改为 jdbccursorItemReader 类型,则会在 Step reader() 中抛出类型异常。

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

解决方法

您正在 JdbcCursorItemReaderread 方法中创建一个 AllocationReader 实例。这是不正确的。此方法的代码应该是实际 read 操作的实现,而不是用于创建项目阅读器。

我无法在批处理配置中将 Item reader 编写为 bean,因为我需要在 step in item reader 之前调用以访问步骤执行。

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

@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 的 item reader bean 时,你需要让 bean 定义方法至少返回 ItemStreamReader(或者实际的实现类型),这样 Spring Batch 才能正确地对bean 并在该步骤中适当地调用 open/update/close。否则,将不会调用 open 方法,因此您将获得 ReaderNotOpenException

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。