title: How to run a step in a loop in Spring Batch : Updated
body: <p>I have below spring batch job:</p>
  
  <pre><code>&lt;job id="MyBatchJob" job-repository="jobRepository"&gt;
  
    &lt;step id="ConfigurationReadStep"&gt;
          &lt;tasklet ref="ConfigurationReadTasklet"  transaction-manager="jobRepository-transactionManager"/&gt;
          &lt;next on="COMPLETED"  to="NextStep" /&gt;  
    &lt;/step&gt;        
  
    &lt;step id="NextStep"&gt;
      &lt;tasklet transaction-manager="jobRepository-transactionManager"&gt;
          &lt;chunk reader="myItemReader" writer="myItemWriter" commit-interval="1000"/&gt;
      &lt;/tasklet&gt;
    &lt;/step&gt;
  
       &lt;listeners&gt;
          &lt;listener ref="jobListener" /&gt;
       &lt;/listeners&gt;     
  
  &lt;/job&gt;
  </code></pre>
  
  <p>It has first step as a configuration read step where after some business logic, I come across with a list of queries. For e.g. say 10 queries. I know that I can promote this list using <code>JobExecutionContext</code> and <code>PromotionListener</code>.</p>
  
  <p>However, I want to feed this queries 1 by 1 to my next step's reader as reader query and run that step in a loop till all the reader queries are consumed. I want to run each of this queries as a spring batch scenario as they may return huge number of items.</p>
  
  <p>How can I do this ? </p>
  
  <p>*********************************** Update **********************************</p>
  
  <p>This is what I am trying to do:</p>
  
  <pre><code>&lt;job id="MyJob" job-repository="jobRepository"&gt;
  
        &lt;step id="ConfigurationReadStep"&gt;
              &lt;tasklet ref="ConfigurationReadTasklet"  transaction-manager="jobRepository-transactionManager"/&gt;
              &lt;next on="COMPLETED"  to="MyNextStep" /&gt;    
               &lt;listeners&gt;
                  &lt;listener ref="promotionListener"/&gt;
              &lt;/listeners&gt;
        &lt;/step&gt;        
  
      &lt;step id="MyNextStep" next="limitDecision"&gt;
          &lt;tasklet transaction-manager="jobRepository-transactionManager"&gt;
              &lt;chunk reader="MyItemReader" writer="MyItemWriter" commit-interval="1000"/&gt;
          &lt;/tasklet&gt;
      &lt;/step&gt;
  
      &lt;decision id="limitDecision" decider="limitDecider"&gt;
          &lt;next on="CONTINUE" to="MyNextStep" /&gt;
          &lt;end on="COMPLETED" /&gt;
      &lt;/decision&gt;
  
       &lt;listeners&gt;
          &lt;listener ref="jobListener" /&gt;
       &lt;/listeners&gt;
  
    &lt;/job&gt;
  
  &lt;beans:bean id="jobListener" class="com.hsbc.gbm.dml.integration.batch.listener.SimpleJobListener" /&gt;
  
  &lt;beans:bean id="promotionListener" class="org.springframework.batch.core.listener.ExecutionContextPromotionListener"&gt;
      &lt;beans:property name="keys" value="readerLimit,readerQueries,readerSQL" /&gt;
  &lt;/beans:bean&gt;
  
    &lt;beans:bean id="ConfigurationReadTasklet" class="com.mypackage.ConfigurationReadTasklet" scope="step"&gt;
    &lt;/beans:bean&gt;
  
  &lt;beans:bean id="MyItemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step"&gt;
      &lt;beans:property name="dataSource" ref="myDataSource" /&gt;
      &lt;beans:property name="sql" value="#{jobExecutionContext['readerSQL']}" /&gt;
      &lt;beans:property name="rowMapper"&gt;
          &lt;beans:bean  name="mapper" class="com.mypackage.MyRowMapper" /&gt;
      &lt;/beans:property&gt;
  &lt;/beans:bean&gt;
  
  &lt;beans:bean id="MyItemWriter" class="com.mypackage.MyItemWriter" scope="step"&gt;
      &lt;beans:constructor-arg ref="myDataSource" /&gt;
  &lt;/beans:bean&gt;
  
  &lt;beans:bean id="limitDecider" class="com.mypackage.StepLoopLimitDecider" scope="step"&gt; 
      &lt;beans:property name="readerQueries" value="#{jobExecutionContext['readerQueries']}" /&gt;
  &lt;/beans:bean&gt;     
  </code></pre>
  
  <p>In the tasklet, I will get list of reader queries. I will set <code>readerQuery</code> as first of these and go to next step which will run normally as a spring batch step.</p>
  
  <p>Once this completes, I want my <code>Decider</code> to check if there are more reader queries, if yes, it will change <code>readerQuery</code> to next query and re-run <code>NextStep</code>, else the job will complete. Below is my Decider:</p>
  
  <pre><code>public class StepLoopLimitDecider implements JobExecutionDecider {
  
  private List&lt;String&gt; readerQueries;
  
  private int count = 1;
  
  public FlowExecutionStatus decide(JobExecution jobExecution,StepExecution stepExecution) {
      if (count &gt;= this.readerQueries.size()) {
          return new FlowExecutionStatus("COMPLETED");
      }
      else {
          System.out.println(count + ": "+readerQueries.get(count));
          jobExecution.getExecutionContext().put("readerSQL", readerQueries.get(count));
          count = count + 1;
          return new FlowExecutionStatus("CONTINUE");
      }
  }
  
  public void setReaderQueries(List&lt;String&gt; readerQueries) {
      this.readerQueries = readerQueries;
  }   
  }
  </code></pre>
  
  <p>However, this is not working. Step runs correctly the first time. But the Decider fails with below error:</p>
  
  <pre><code>    2016-12-06 14:46:24 ERROR AbstractJob:306 - Encountered fatal error executing job
  org.springframework.batch.core.JobExecutionException: Flow execution ended unexpectedly
      at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:141)
      at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
      at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
      at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:48)
      at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:114)
      at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:348)
      at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:565)
  Caused by: 
  org.springframework.batch.core.job.flow.FlowExecutionException: Ended flow=MyBatchJob at state=MyBatchJob.limitDecision with exception
      at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:152)
      at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
      at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
      ... 6 more
  Caused by: 
  org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.limitDecider': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:339)
      at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
      at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:33)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:182)
      at $Proxy4.decide(Unknown Source)
      at org.springframework.batch.core.job.flow.support.state.DecisionState.handle(DecisionState.java:43)
      at org.springframework.batch.core.configuration.xml.SimpleFlowFactoryBean$DelegateState.handle(SimpleFlowFactoryBean.java:141)
      at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
      ... 8 more
  Caused by: 
  java.lang.IllegalStateException: No context holder available for step scope
      at org.springframework.batch.core.scope.StepScope.getContext(StepScope.java:197)
      at org.springframework.batch.core.scope.StepScope.get(StepScope.java:139)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
      ... 15 more
  </code></pre>
  
  <p>Can someone please help me with making this work.</p>