You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Batch项目报错JobRepository is mandatory,求修改方案

Spring Batch 报错解决:JobRepository is mandatory

作为Spring Batch初学者,参照官方指南开发简单项目时,运行出现JobRepository is mandatory错误,以下是问题代码、报错信息及修改方案:

问题代码

Controller代码

@RestController
@RequestMapping("/jobs")
public class JobController {

    @Autowired
    private JobLauncher jobLauncher;
    @Autowired
    private Job job;
    
    @Value("${app.version}")
    private String appVersion;
    
    @GetMapping
    @RequestMapping("/")
    public Map getStatus() {
        Map map = new HashMap<String, String>();
        map.put("app-version", appVersion);
        return map;
    }


    @PostMapping("/importCustomers")
    public void importCsvToDBJob() {
        JobParameters jobParameters = new JobParametersBuilder()
                .addLong("startAt", System.currentTimeMillis()).toJobParameters();
        try {
            jobLauncher.run(job, jobParameters);
        } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) {
            e.printStackTrace();
        }
    }
}

Job Config配置代码

@Configuration
@EnableBatchProcessing
@AllArgsConstructor
@NoArgsConstructor
public class SpringBatchConfig {
    
    private CustomerRepository repo;

    @Bean
    public FlatFileItemReader<Customer> reader() {
        FlatFileItemReader<Customer> itemReader = new FlatFileItemReader<>();
        itemReader.setResource(new FileSystemResource("src/main/resources/customers.csv"));
        itemReader.setName("csvReader");
        itemReader.setLinesToSkip(1);
        itemReader.setLineMapper(lineMapper());
        return itemReader;
    }

    private LineMapper<Customer> lineMapper() {
        DefaultLineMapper<Customer> lineMapper = new DefaultLineMapper<>();

        DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
        lineTokenizer.setDelimiter(",");
        lineTokenizer.setStrict(false);
        lineTokenizer.setNames("id", "firstName", "lastName", "email", "gender", "contactNo", "country", "dob");

        BeanWrapperFieldSetMapper<Customer> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
        fieldSetMapper.setTargetType(Customer.class);

        lineMapper.setLineTokenizer(lineTokenizer);
        lineMapper.setFieldSetMapper(fieldSetMapper);
        return lineMapper;

    }

    @Bean
    public CustomerProcessor processor() {
        return new CustomerProcessor();
    }

   
    @Bean
    public JdbcBatchItemWriter<Customer> writer(DataSource dataSource) {
      return new JdbcBatchItemWriterBuilder<Customer>()
        .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
        .sql("INSERT INTO CUSTOMERS_INFO (CUSTOMER_ID, FIRST_NAME, LAST_NAME, EMAIL, GENDER, CONTACT, COUNTRY, DOB) VALUES (:id, :firstName, :lastName, :email, :gender, :contactNo, :country, :dob)")
        .dataSource(dataSource)
        .build();
    }

    @Bean
    public Step step1(JobRepository jobRepository,
            PlatformTransactionManager transactionManager, JdbcBatchItemWriter<Customer> writer) {
          return new StepBuilder("step1")
            .<Customer, Customer> chunk(10)
            .reader(reader())
            .processor(processor())
            .writer(writer)
            .taskExecutor(taskExecutor())
            .build();
        }
    
    @Bean
    public Job importCustomers(JobRepository jobRepository,
        JobCompletionNotificationListener listener, Step step1) {
      return new JobBuilder("importCustomers")
        .incrementer(new RunIdIncrementer())
        .listener(listener)
        .flow(step1)
        .end()
        .build();
    }
    
    @Bean
    public TaskExecutor taskExecutor() {
        SimpleAsyncTaskExecutor asyncTaskExecutor = new SimpleAsyncTaskExecutor();
        asyncTaskExecutor.setConcurrencyLimit(10);
        return asyncTaskExecutor;
    }

}

完整报错信息

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jobController': Unsatisfied dependency expressed through field 'job'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'importCustomers' defined in class path resource [com/javatechie/spring/batch/config/SpringBatchConfig.class]: Unsatisfied dependency expressed through method 'importCustomers' parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'step1' defined in class path resource [com/javatechie/spring/batch/config/SpringBatchConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.batch.core.Step]: Factory method 'step1' threw exception; nested exception is org.springframework.batch.core.step.builder.StepBuilderException: java.lang.IllegalStateException: JobRepository is mandatory

问题原因

构建Step和Job时,虽然注入了JobRepository和PlatformTransactionManager参数,但未将它们绑定到对应的构建器实例上。Spring Batch要求Step必须关联JobRepository来管理批处理状态,同时需要TransactionManager处理事务;Job也必须关联JobRepository才能正常初始化。

修改方案

1. 修正Step构建方法

在StepBuilder中显式关联JobRepository和TransactionManager,有两种写法:

写法一:构造器传入

@Bean
public Step step1(JobRepository jobRepository,
        PlatformTransactionManager transactionManager, JdbcBatchItemWriter<Customer> writer) {
      return new StepBuilder("step1", jobRepository) // 构造器传入JobRepository
        .<Customer, Customer> chunk(10, transactionManager) // chunk方法传入TransactionManager
        .reader(reader())
        .processor(processor())
        .writer(writer)
        .taskExecutor(taskExecutor())
        .build();
    }

写法二:调用builder方法绑定

@Bean
public Step step1(JobRepository jobRepository,
        PlatformTransactionManager transactionManager, JdbcBatchItemWriter<Customer> writer) {
      return new StepBuilder("step1")
        .repository(jobRepository) // 绑定JobRepository
        .transactionManager(transactionManager) // 绑定TransactionManager
        .<Customer, Customer> chunk(10)
        .reader(reader())
        .processor(processor())
        .writer(writer)
        .taskExecutor(taskExecutor())
        .build();
    }

2. 修正Job构建方法

在JobBuilder构造器中传入JobRepository:

@Bean
public Job importCustomers(JobRepository jobRepository,
    JobCompletionNotificationListener listener, Step step1) {
  return new JobBuilder("importCustomers", jobRepository) // 构造器传入JobRepository
    .incrementer(new RunIdIncrementer())
    .listener(listener)
    .flow(step1)
    .end()
    .build();
}

补充说明

  • @EnableBatchProcessing注解会自动配置JobRepository和PlatformTransactionManager(前提是项目已正确配置数据源),无需手动定义这两个Bean。
  • 确保项目配置文件(application.properties/yml)中包含正确的数据库连接信息,JobRepository需要依赖数据源存储批处理元数据。

内容的提问来源于stack exchange,提问作者Satya Priya Biswas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 01:07:09