javaspring-boot

When multiple batch job files are there , only the initial one is running every time in SpringBoot


I have 2 batch configuration files with different bean names, but whenever I am building my application and hitting with a request payload, It is pointing to the first batch job file instead of the designated one.

BatchConfiguration : Initial batch job configuration file BatchConfigurationV2 : Second batch job configuration file

This is how I am initializing my job builder for BatchConfiguration (first batch job configuration file) :

@Bean
public Job jsonProcessingJob(JobRepository jobRepository, Step jsonProcessingStep) {
        return new JobBuilder("jsonProcessingJob", jobRepository)
                .incrementer(new RunIdIncrementer())
                .listener(jobExecutionListener())
                .start(jsonProcessingStep)
                .build();
    }


JobExecution jobExecution;
jobExecution = jobLauncher.run(jsonProcessingJob, jobParameters);
//here jsonProcessingJob is the job name for the first batch config file.
ExecutionContext context = jobExecution.getExecutionContext();

And for the second:

@Bean
    public Job jsonProcessingJobV2(JobRepository jobRepository, Step jsonProcessingStepV2) {
        return new JobBuilder("jsonProcessingJobV2", jobRepository)
                .incrementer(new RunIdIncrementer())
                .listener(jobExecutionListenerV2())
                .start(jsonProcessingStepV2)
                .build();
    }

jobExecution = jobLauncherV2.run(jsonProcessingJobV2, jobParameters);
            ExecutionContext context = jobExecution.getExecutionContext();

I want that if I have initialized the second batch, job file to be executed. So, it should only pick up the configuration file pointing to the second BatchConfiguration file rather than the first.


Solution

  • this problem arises because springBoot considers the initially configured beans as the primary beans and by default , accounts for only one configuration class for SpringBatch. Hence , if the initially defined batchJob configuration is already there , it will require some differentiation between multiple batch configuration classes.
    there are many solutions to this problem :
    -> Making the beans defined in the batchConfiguration files as primary by adding @Primary annotation , so that springBoot can differentiate between the primary and secondary beans .

    But , it would give us problems if there are more than two configuration files present in the scenario.
    Hence the usage of @Qualifier annotation will be the best suited option .

    @Bean
    @Qualifier("jsonProcessingJobBeanV1")
    public Job jsonProcessingJob(JobRepository jobRepository, Step jsonProcessingStep) {
            return new JobBuilder("jsonProcessingJob", jobRepository)
                    .incrementer(new RunIdIncrementer())
                    .listener(jobExecutionListener())
                    .start(jsonProcessingStep)
                    .build();
        }
    

    and similarly for the stepBuilder , ItemReader , ItemWriter and ItemProcessor also , we will define the @Qualifier names.
    Example (ItemReader) :

    @Bean
    @Qualifier("ItemReaderV1")
    @StepScope
    public ItemReader<ItemEntity> jsonItemReader(@Value("#{jobParameters['fileName']}") String fileName) {
    

    In the same manner we are supposed to annotate all the beans. And your problem will be solved .