【问题标题】:Spring Batch - ItemWriter is writing same object read by ItemReader but not the one returned after processing through ItemProcessorSpring Batch - ItemWriter 正在写入 ItemReader 读取的相同对象,但不是通过 ItemProcessor 处理后返回的对象
【发布时间】:2021-01-04 13:23:44
【问题描述】:

我的场景是:JdbcPagingItemReader 正在从 Oracle 数据库读取并返回对象,比如说“员工”。然后这个 'Employee' 对象被传递给 Processor 以再次调用 db 以从多个表中提取更多信息并返回 'AggregatedEmployee' 对象(它实际上扩展了 Employee)。我正在使用 KafkaItemWriter 将处理后的对象写入 Kafka,而不是写入 AggregatedEmployee,作者正在尝试编写 'Employee' 本身。

@Mahmoud Ben Hassine:我看到了你对 Spring Batch 的很多建议。请分享你的想法。

处理器接口代码:

public interface PageProcessor<T> {
       <R extends Employee> R process(T page);
}

步骤 Bean 代码:

@Bean
protected Step step1 (CompositeJdbcPagingItemReader <Employee> reader, KafkaItemWriter <String, AggregatedEmployee> writer) {
    return steps.get("step1")
                .<Employee, AggregatedEmployee>chunk(5).
                reader(reader).
                writer(writer).build();
    }

处理器接口代码的实现类:

public class EmployeeProcessor implements PageProcessor<Employee> {
    private NamedParameterJdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource) {
        jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <R extends Employee> R process(Employee page) {
             ... implementation goes here
    }

KafkaItemWriter Bean:

    @Bean
    KafkaItemWriter<String,AggregatedEmployee> writer(){
        return new KafkaItemWriterBuilder<String, AggregatedEmployee>()
                .kafkaTemplate(aggregatedEmployeekafkaTemplate)
                .itemKeyMapper(aggregatedEmployee -> String.valueOf(aggregatedEmployee.getEmployeeId()))
                .build();
    }

编辑显示处理器:

public class CompositeJdbcPagingItemReader<T> extends JdbcPagingItemReader<T> {
    private PageProcessor<T> pageProcessor;

    public void setPageProcessor(PageProcessor<T> pageProcessor) {
        this.pageProcessor = pageProcessor;
    }

当 Reader bean 被创建时,处理器对象也被创建并通过上面显示的 setter 设置到 reader 中,写入 EmployeeProcessor 的处理器逻辑也被执行。

错误:

java.lang.ClassCastException: class com.sample.model.Employee cannot be cast to class com.sample.model.AggregatedEmployee (com.sample.model.Employee and com.sample.model.AggregatedEmployee are in unnamed module of loader 'app')
    at org.springframework.batch.item.KeyValueItemWriter.write(KeyValueItemWriter.java:43)

【问题讨论】:

  • 删除 @SuppressWarnings("unchecked") 并检查警告的位置。你的类型是错误的。

标签: java spring spring-boot apache-kafka spring-batch


【解决方案1】:

您没有在您的步骤上设置处理器:

@Bean
protected Step step1 (CompositeJdbcPagingItemReader <Employee> reader, KafkaItemWriter <String, AggregatedEmployee> writer) {
return steps.get("step1")
            .<Employee, AggregatedEmployee>chunk(5).
            reader(reader).
            writer(writer).build();
}

您需要设置将在您的步骤上进行类型转换的处理器Employee -> AggregatedEmployee

【讨论】:

  • 我忘了提到我的处理器是在阅读器本身中配置的,如下所示。请参阅上面编辑的代码段
  • 这不是一个好主意,您的阅读器同时做两件事并与您的处理器耦合。此外,Spring Batch 不会调用您的处理器,因此不会发生 EmployeeAggregatedEmployee 的转换,这就是您的问题的原因。
  • 感谢马哈茂德·本·哈辛。我将处理器从阅读器中分离出来,一切都按预期工作。
  • 好的,很高兴它有帮助!在这种情况下,请接受答案:stackoverflow.com/help/someone-answers。请注意,接受答案与投票不同。
猜你喜欢
  • 2019-08-02
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-15
  • 2017-08-31
相关资源
最近更新 更多