1
votes

The Spring Batch documentation does a pretty good job explaining how to correctly define a job with steps that pattern this:

call Step 1
if (some condition determined by a Decider) {
  call Step 2
} ELSE {
  call Step 3
}

However, I'm trying to achieve THIS in Java config:

call Step 1
if (some condition determined by a decider) {
 call step 2
}
call step 3
call step 4
.. so on and so forth ..

and I think I might be misreading the API because I can't seem to get the conditional IF logic to behave as one would expect -- all that happens is when the decider evaluates to True it runs step 2 but never runs Step 3 .. and of course when the decider evaluates to false it runs only step 3. Does anybody have any examples for how to do a conditional step of this sort in Java config?

1
Can you post the actual code/xml you're using to manage the job stesp currently so members may advise? - Atmas
all that happens is when the decider evaluates to True it runs step 2 but never runs Step 3: as mentioned by Atmas, please share your code or provide a minimal example that reproduces that issue to be able to help you. - Mahmoud Ben Hassine

1 Answers

3
votes

you should define your decider, for that you have two choices. A class that implements JobExecutionDecider or to define a bean as shown in the above example :

@Bean
public JobExecutionDecider decider() {
    return (JobExecution jobExecution, StepExecution stepExecution) -> {
        // write code here
        boolean someCondition = true;
        return someCondition ? new FlowExecutionStatus("COMPLETED") : new FlowExecutionStatus("FAILED");
    };
}

after that, you can define your flow using this decider like this :

@Bean
public Job job() {
    return jobBuilderFactory.get("job").incrementer(new RunIdIncrementer()).start(step1()).next(decider())
            .on("COMPLETED").to(step2()).from(decider()).on("FAILED").to(step3()).end().build();
}

the whole definition of your job with steps should look like this :

@Configuration
public class MJob {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job job() {
        return jobBuilderFactory.get("job").incrementer(new RunIdIncrementer()).start(step1()).next(decider())
                .on("COMPLETED").to(step2()).from(decider()).on("FAILED").to(step3()).end().build();
    }

    @Bean
    public JobExecutionDecider decider() {
        return (JobExecution jobExecution, StepExecution stepExecution) -> {
            // write code here
            boolean someCondition = true;
            return someCondition ? new FlowExecutionStatus("COMPLETED") : new FlowExecutionStatus("FAILED");
        };
    }

    public Step step1() {
        return stepBuilderFactory.get("step1").tasklet(new Step1()).build();
    }

    public Step step2() {
        return stepBuilderFactory.get("step2").tasklet(new Step2()).build();
    }

    public Step step3() {
        return stepBuilderFactory.get("step3").tasklet(new Step3()).build();
    }

}

Is this answer your question?