As we can see in Spring batch official documentation "Passing Data to Future Steps - Spring Batch" is possible but most of us have been struggling with it because in the official documentation they have mentioned the two possibilities. Step level and one at the Job level. The problem is how to retrieve the data at the step level?
My solution was the same as they related in official documentation but it didn't work. So I decided to do the following:
1- Create bean for promotion listener:
<beans:bean id="promotionListener"
class="org.springframework.batch.core.listener.ExecutionContextPromotionListener">
<beans:property name="keys" value="someValues"/>
</beans:bean>
2- Set the listener in your step (The step you wish to save the data)
<listeners>
<listener ref="promotionListener"/>
</listeners>
3- In the same step (the step in which the data will be saved) in your writer, you save the data.
private StepExecution stepExecution;
@BeforeStep
public void saveStepExecution(StepExecution stepExecution) {
this.stepExecution = stepExecution;
ExecutionContext executionContext = stepExecution.getExecutionContext();
Map<String, String> fieldsMap= new HashMap<>();
executionContext.put("keys", someValues);
}
@Override
public void write(List<? extends Map<String, String>> items) throws Exception {
LOGGER.info(items.toString());
Map<String, String> fieldsMap= new ConcurrentHashMap<>();
items.forEach(item -> item.forEach(fieldsMap::put));
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("keys", fieldsMap);
}
You can see, in my case I am saving the data in a Map (ConcurrentHashMap).
4- IMPORTANT: In the next step, you want to retrieve the data that we saved in the previous step. In that order, we must do:
Declare the object which will hold the value that we will retrieve as:
private Map fieldsMap;
Pay attention to JobExecution
@BeforeStep
public void retrieveInterStepData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
Collection<StepExecution> stepExecutions = jobExecution.getStepExecutions();
for (StepExecution steps : stepExecutions) {
ExecutionContext executionContext = steps.getExecutionContext();
if (executionContext.containsKey("keys")) {
this.nationalityMap = (Map<String, String>) executionContext.get("keys");
}
}
}
That's it! You may wonder why I didn't follow the way it is written in official documentation? The reason is that I am working with Steps in the same job. They share the same job execution. Now take a look at the picture of my debugging mode.
Suggestion please if there is another way.
NOTE: Please don't just copy and paste code form official documentation, provide your own answer or implementation.
The link of spring batch documentation which relates about this issue is below enter link description here