spring批处理:需要一个名为“dataSource”的bean,但无法找到

问题描述 投票:0回答:1

我正在将 Spring Boot 从版本 2.6.6 升级到 3.1.3。

我通过参考this sof帖子进行了所需的JobRepository相关修改。

一切似乎都很顺利,但随后我面临以下错误 -

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 1 of method stepOne in com.mycompany.retail.esl.data_manager_job.product_publisher_job.ProductPublisherJob required a bean named 'dataSource' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Qualifier("PRODUCT_PUBLISHER_JOB_STEP_ONE")


Action:

Consider defining a bean named 'dataSource' in your configuration.

我的步骤生成器和作业生成器代码如下 -

@Configuration
@EnableBatchProcessing
@RequiredArgsConstructor
public class ProductPublisherJob {

  private static final int DEFAULT_CHUNK_SIZE = 25;
  public static final String JOB_NAME = JobName.PRODUCT_PUBLISHER_JOB;

  @Bean(ProductPublisherJob.JOB_NAME)
  public Job job(
      @Qualifier(ProductPublisherJob.JOB_NAME + "_STEP_ONE") Step stepOne,
      JobRepository jobRepository,
      JobExecutionListener jobExecutionListener,
      @Qualifier("ArticleFlatFilePublisher") ArticleFlatFilePublisher articleFlatFilePublisher
  ) {
    return new JobBuilder(ProductPublisherJob.JOB_NAME, jobRepository)
        .incrementer(new RunIdIncrementer())
        .flow(stepOne)
        .end()
        .listener(jobExecutionListener)
        .listener(articleFlatFilePublisher)
        .build();
  }

  @Bean(ProductPublisherJob.JOB_NAME + "_STEP_ONE")
  public Step stepOne(
      @Qualifier("ProductPublisherJobPageReader") ProductPublisherJobPageReader pageReader,
      JobRepository jobRepository,
      @Qualifier("ProductItemProcessor") ProductItemProcessor itemProcessor,
      @Qualifier("ArticleFlatFileWriter") ArticleFlatFileWriter itemWriter
  ) {
    return new StepBuilder(ProductPublisherJob.JOB_NAME + "_ONE", jobRepository)
        .<Product, Article>chunk(DEFAULT_CHUNK_SIZE)
        .reader(pageReader)
        .processor(itemProcessor)
        .writer(itemWriter)
        .build();
  }
}

我确实在 application.properties 中定义了所需的数据源属性,而且它在 Spring Boot 2.6.6 中运行良好。
对于如何解决这个问题,有任何的建议吗。任何帮助将不胜感激,因为这对我来说是一个阻碍。

编辑 1 - 重新分级所需的数据源 bean

我在 application.properties 中有以下内容

spring.batch.datasource.driver-class-name = org.h2.Driver
spring.batch.datasource.password = sa
spring.batch.datasource.url = jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;
spring.batch.datasource.username = sa

在 build.gradle 中我有 -

implementation "com.h2database:h2:2.2.224"
implementation "org.springframework.boot:spring-boot-starter-batch"
implementation "org.springframework.boot:spring-boot-starter-data-jpa"

我还需要做些什么才能将数据源 Bean 放入应用程序上下文吗?

编辑 2 - 显式添加数据源 bean。
我明确地将以下 bean 定义添加到配置类中。

@Bean
public DataSource dataSource() {
  DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(
  dataSourceBuilder.driverClassName("org.h2.Driver");
  dataSourceBuilder.url("jdbc:h2:mem:test");
  dataSourceBuilder.username("SA");
  dataSourceBuilder.password("");
  return dataSourceBuilder.build();
}

它建议:

考虑在您的应用程序中定义一个名为“transactionManager”的 bean 配置。

所以我添加了-

@Bean
public PlatformTransactionManager transactionManager() {
  return new DataSourceTransactionManager(dataSource());
}

但现在它给出了另一个仍然与 transactionManager 相关的错误 -

org.springframework.beans.factory.UnsatisfiedDependencyException: 创建类中定义的名称为“Product_PUBLISHER_JOB”的 bean 时出错 路径资源 [com/wayfair/retail/esl/data_manager_job/product_publisher_job/ProductPublisherJob.class]: 通过方法“job”参数 0 表示不满足的依赖关系: 创建定义了名称“Product_PUBLISHER_JOB_STEP_ONE”的 bean 时出错 在类路径资源中 [com/wayfair/retail/esl/data_manager_job/product_publisher_job/ProductPublisherJob.class]: 无法实例化[org.springframework.batch.core.Step]:工厂 方法“stepOne”抛出异常并显示消息: java.lang.IllegalStateException:事务管理器必须是 提供

我明确提供了事务管理器,但为什么它还是抱怨。

编辑 3 - 根据 Gurkan 的要求编写条目代码。

@Component("ArticleFlatFileWriter")
public class ArticleFlatFileWriter extends FlatFileItemWriter<Article> {

  private final ArticleMapper articleMapper;
  ArticleFlatFileWriter(
      @Value("${app.storage.localFile}") String file,
      @Value("${app.storage.file.csv.header}") Boolean includeHeader,
      @Qualifier("ArticleLineAggregator") ArticleLineAggregator lineAggregator,
      ArticleMapper articleMapper
  ) {
    super();

    if (Boolean.TRUE.equals(includeHeader)) {
      this.setHeaderCallback(this::headerCallback);
    }

    var fileSystemResource = new FileSystemResource(file);

    this.setAppendAllowed(true);
    this.setEncoding("UTF-8");
    this.setLineAggregator(lineAggregator);
    this.setResource(fileSystemResource);
    this.setShouldDeleteIfExists(true);
    this.articleMapper = articleMapper;
  }

  private void headerCallback(Writer writer) throws IOException {
    writer.write(String.join(ArticleLineTokenizer.DEFAULT_DELIMITER, this.articleMapper.getHeaderNames()));
  }

  protected boolean isAppendAllowed() {
    return this.append;
  }
}

编辑4- 将 StepBuilder 代码更新到下面后(也像 Skillup 所建议的那样),事务管理器问题得到解决,但我面临

Error creating bean with name 'jpaMappingContext': JPA metamodel must not be empty
我为此发布了一个新问题。

@Bean(UpdateAssignedProductsJob.JOB_NAME + "_STEP_ONE")
public Step stepOne(
    @Qualifier("UpdateAssignedProductsJobPagedItemReader") UpdateAssignedProductsJobPagedItemReader itemReader,
    JobRepository jobRepository, PlatformTransactionManager transactionManager,
    @Qualifier("ProductItemProcessor") ProductItemProcessor itemProcessor,
    @Qualifier("ArticleFlatFileWriter") ArticleFlatFileWriter itemWriter
) {
   return new StepBuilder(UpdateAssignedProductsJob.JOB_NAME + "_STEP_ONE", jobRepository)
      .<Product, Article>chunk(DEFAULT_CHUNK_SIZE, transactionManager)
      .reader(itemReader)
      .processor(itemProcessor)
      .writer(itemWriter)
      .build();
}
spring spring-boot spring-batch spring-3
1个回答
1
投票

您应该像这样替换步骤的代码:

  @Bean(ProductPublisherJob.JOB_NAME + "_STEP_ONE")
  public Step stepOne( JobRepository jobRepository,PlatformTransactionManager transactionManager,
      @Qualifier("ProductPublisherJobPageReader") ProductPublisherJobPageReader pageReader,
      @Qualifier("ProductItemProcessor") ProductItemProcessor itemProcessor,
      @Qualifier("ArticleFlatFileWriter") ArticleFlatFileWriter itemWriter
  ) {
    return new StepBuilder(ProductPublisherJob.JOB_NAME + "_ONE", jobRepository)
        .<Product, Article>chunk(DEFAULT_CHUNK_SIZE, transactionManager)
        .reader(pageReader)
        .processor(itemProcessor)
        .writer(itemWriter)
        .build();
  }  
© www.soinside.com 2019 - 2024. All rights reserved.