title: Passing Data to Future Steps - Spring Batch
body: <p>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. <strong>Step level</strong> and one at the <strong>Job level</strong>. The problem is how to retrieve the data at the step level?</p>
  
  <p>My solution was the same as they related in official documentation but it didn't work. So I decided to do the following:</p>
  
  <p><strong>1- Create bean for promotion listener:</strong></p>
  
  <pre><code>&lt;beans:bean id="promotionListener"
                  class="org.springframework.batch.core.listener.ExecutionContextPromotionListener"&gt;
          &lt;beans:property name="keys" value="someValues"/&gt;
  &lt;/beans:bean&gt;
  </code></pre>
  
  <p><strong>2- Set the listener in your step (The step you wish to save the data)</strong>         </p>
  
  <pre><code>        &lt;listeners&gt;
              &lt;listener ref="promotionListener"/&gt;
          &lt;/listeners&gt;
  </code></pre>
  
  <p><strong>3- In the same step (the step in which the data will be saved) in your writer, you save the data.</strong></p>
  
  <pre><code>private StepExecution stepExecution;
  
      @BeforeStep
      public void saveStepExecution(StepExecution stepExecution) {
          this.stepExecution = stepExecution;
  
          ExecutionContext executionContext = stepExecution.getExecutionContext();
          Map&lt;String, String&gt; fieldsMap= new HashMap&lt;&gt;();
          executionContext.put("keys", someValues);
      }
  
  @Override
  public void write(List&lt;? extends Map&lt;String, String&gt;&gt; items) throws Exception {
      LOGGER.info(items.toString());
  
      Map&lt;String, String&gt; fieldsMap= new ConcurrentHashMap&lt;&gt;();
      items.forEach(item -&gt; item.forEach(fieldsMap::put));
  
      ExecutionContext stepContext = this.stepExecution.getExecutionContext();
      stepContext.put("keys", fieldsMap);
  }
  </code></pre>
  
  <p>You can see, in my case I am saving the data in a Map (ConcurrentHashMap).</p>
  
  <p><strong>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:</strong></p>
  
  <ul>
  <li><p>Declare the object which will hold the value that we will retrieve as:</p>
  
  <p>private Map fieldsMap;</p></li>
  </ul>
  
  <p>Pay attention to <strong>JobExecution</strong></p>
  
  <p><a href="https://i.stack.imgur.com/JUjyp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JUjyp.png" alt="enter image description here"></a></p>
  
  <pre><code>@BeforeStep
      public void retrieveInterStepData(StepExecution stepExecution) {
          JobExecution jobExecution = stepExecution.getJobExecution();
          Collection&lt;StepExecution&gt; stepExecutions = jobExecution.getStepExecutions();
          for (StepExecution steps : stepExecutions) {
              ExecutionContext executionContext = steps.getExecutionContext();
              if (executionContext.containsKey("keys")) {
                  this.nationalityMap = (Map&lt;String, String&gt;) executionContext.get("keys");
              }
          }
      }
  </code></pre>
  
  <p>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.</p>
  
  <p>Suggestion please if there is another way.</p>
  
  <p>NOTE: Please don't just copy and paste code form official documentation, provide your own answer or implementation. </p>
  
  <p>The link of spring batch documentation which relates about this issue is below
  <a href="https://docs.spring.io/spring-batch/trunk/reference/html/patterns.html#passingDataToFutureSteps" rel="nofollow noreferrer">enter link description here</a></p>