How can we get the JobId in the RetryContext?

538 views Asked by At

I am just extending my this question here - Spring Retry doesn't works when we use RetryTemplate?.

How can we get the JobId in the RetryContext ?

I went through link: Spring Batch how to configure retry period for failed jobs, but still did not know.

@Component
@Slf4j
public class RecoveryCallback implements RecoveryCallback<String>{
    @Autowired
    private NamedParameterJdbcTemplate namedJdbcTemplate;
    
    @Autowired
    private AbcService abcService;
    
    @Value("#{stepExecution.jobExecution.jobId}")
    private Long jobId;
        
    @Override
    public String recover(RetryContext context) throws Exception {
        log.warn("RecoveryCallback | recover is executed ...");
        
        ErrorLog errorLog = ErrorLog.builder()
                .jobName("ABC")
                .stepName("RETRY_STEP")
                .stepType("RETRY")
                ....
                ....
                ....
                .jobId(jobId)
                .build();
        abcService.updateErrLog(errorLog);
        
        return "Batch Job Retried and exausted with all attemps";
    }
}
1

There are 1 answers

4
Mahmoud Ben Hassine On BEST ANSWER

Since you are injecting stepExecution.jobExecution.jobId in a field of a Spring bean, you need to make this bean Step scoped. With this approach, the RetryContext is not used.

If you want to use the retry context, then you need to put the jobId in the context in the retryable method first. From your linked question:

retryTemplate.execute(retryContext  -> {
        JobExecution jobExecution = jobLauncher.run(sampleAcctJob, pdfParams);
        if(!jobExecution.getAllFailureExceptions().isEmpty()) {
            log.error("============== sampleAcctJob Job failed, retrying.... ================");
            throw jobExecution.getAllFailureExceptions().iterator().next();
        }
        logDetails(jobExecution);
        // PUT JOB ID in retryContext
        retryContext.setAttribute("jobId", jobExecution.getExecutionId());
        return jobExecution;
    });

With that, you can get the jobId from the context in the recover method:

@Override
public String recover(RetryContext context) throws Exception {
    log.warn("RecoveryCallback | recover is executed ...");
    
    ErrorLog errorLog = ErrorLog.builder()
            .jobName("ABC")
            .stepName("RETRY_STEP")
            .stepType("RETRY")
            ....
            ....
            .jobId(context.getAttribute("jobId"))
            .build();
    abcService.updateErrLog(errorLog);
    
    return "Batch Job Retried and exausted with all attemps";
}