【问题标题】:Spring Batch Writer receives wrong object typeSpring Batch Writer 接收到错误的对象类型
【发布时间】:2020-09-14 04:35:16
【问题描述】:

我在使用 Spring Batch 时遇到了关于我的自定义编写器配置的问题,该编写器基本上是一个 RepositoryItemWriter

@Bean
@StepScope
public ItemReader<DTO> itemReader() {
    [...]Reading from database and mapping into DTO class
    return reader;
}

@Bean
@StepScope
public ItemProcessor<DTO, Entity> itemProcessor(mapper) {
        return dto-> {
            dto.check();
            return mapper.toEntity(dto);
        };
}

@Bean
@StepScope
public ItemWriter<Entity> itemWriter() {
   [...]Save into database from repository
   return writer;
}

@Bean
public Step step() {
    return stepBuilderFactory.get("step")
            .<DTO, Entity>chunk(500)
            .reader(itemReader)
            .writer(itemWriter)
            .build();
}

我正在使用 mapstruct 将 DTO 映射到处理器内的实体。尽管看起来是对的,但我的作者实际上是在接收 DTO 项目而不是实体,因此无法持久化它们。

关于批次结构的一些补充但不相关的信息。我正在从一个大文件中读取,并将其拆分为较小的文件。然后我用多资源分区器对我的步骤进行分区,处理器进行一些格式控制,然后编写器将其批量插入数据库。

编辑: 我想我可以复制/粘贴生成的源代码,但 MapperImpl 非常简单:

   @Override
    public Entity toEntity(DTO dto) {
        if ( dto == null ) {
            return null;
        }
      Entity entity = new Entity();
      [Bunch of controls and mapping]
      return entity;
     }

差不多就是这样。

感谢您的帮助

【问题讨论】:

  • my writer is actually receiving DTO items instead of Entity and thus cannot persist them.: 你是怎么得出这个结论的?如果是这种情况,我看不出代码是如何编译的。你在使用 JPA 吗?您的实体在写入之前是否附加到持久性上下文?这可能是他们没有坚持下去的原因。您使用哪个事务管理器?这也可以发挥作用。
  • 感谢您的评论。 Spring Boot 实际上是自动配置了这批中的几乎所有内容。为了给你更多的上下文,起初我只使用从读者到作者的实体,并且持久化实体没有问题。由于处理需要,我决定使用 DTO 并将其映射到我的实体,以便它可以匹配数据库表。作者抛出这个org.springframework.beans.NotReadablePropertyException: Invalid property 'id' of bean class [my.package.custom.dto.DTO]: Could not find field for property during fallback access!,我在调试作者时看到了 DTO 列表
  • 我实际上在Customize parameters of a step in a spring batch applications这个帖子上看到了你的回答,并用你的例子来说明我的批次。我会检查是否要在我的原始帖子中添加一些内容以更好地说明我的批次。
  • 谢谢@MahmoudBenHassine 和Alex,你们都是对的。我的愚蠢错误,我从我链接的帖子中举了一个例子,但是在我自己的批次中,处理器没有在步骤中使用。所以它直接从读者到作者。这就是你在半夜编码得到的结果:混乱和愚蠢的错误^^。很抱歉浪费了这么多时间。
  • 好的,不用担心,很高兴知道您解决了问题。

标签: java spring spring-batch


【解决方案1】:

return mapper.toEntity(dto);

也许,问题在于映射器的实现。如果没有实现源,很难说 mapper 是如何工作的

【讨论】:

  • 我编辑了我的问题以添加 MapperImpl 生成的代码,因为我无法在评论中正确添加代码。
  • .processor(itemProcessor()) 如果您的 ItemProcessor 使用映射器 arg public ItemProcessor&lt;DTO, Entity&gt; itemProcessor(mapper),为什么不需要任何 arg
  • 我实际上是在使用 bean 注入,括号是我为说明我的帖子而编写的代码中的错误。
  • 检查你是否没有更多的itemProcessor bean。
  • 我没有其他这种类型的 bean,我正在使用限定符注释来防止这类问题。我已经重新启动并使缓存无效+使用 Maven 全新安装重建应用程序。没有改进。我将删除处理器中的 lambda 进行调查,并会及时通知您。
【解决方案2】:

我猜是夜间编码的错误。没有为该步骤声明处理器,因此项目直接从读取器传递到写入器,而不是作为实体进行处理和转换。

@Bean
@StepScope
public ItemReader<DTO> itemReader() {
    [...]Reading from database and mapping into DTO class
    return reader;
}

@Bean
@StepScope
public ItemProcessor<DTO, Entity> itemProcessor(mapper) {
        return dto-> {
            dto.check();
            return mapper.toEntity(dto);
        };
}

@Bean
@StepScope
public ItemWriter<Entity> itemWriter() {
   [...]Save into database from repository
   return writer;
}

@Bean
public Step step() {
    return stepBuilderFactory.get("step")
            .<DTO, Entity>chunk(500)
            .reader(itemReader)
            .processor(itemProcessor) //Edit with solution : This line was missing
            .writer(itemWriter)
            .build();
}

仍然想知道它应该已经编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 2012-06-16
    • 2017-08-20
    • 2023-04-04
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    相关资源
    最近更新 更多