title: Spring Batch restart uncompleted jobs from the same execution and step
body: <p>I use the following logic to restart the Spring Batch uncompleted(for example after application abnormal termination) jobs:</p>
  
  <pre><code>public void restartUncompletedJobs() {
  
      LOGGER.info("Restarting uncompleted jobs");
  
      try {
          jobRegistry.register(new ReferenceJobFactory(documetPipelineJob));
  
          List&lt;String&gt; jobs = jobExplorer.getJobNames();
          for (String job : jobs) {
              Set&lt;JobExecution&gt; runningJobs = jobExplorer.findRunningJobExecutions(job);
  
              for (JobExecution runningJob : runningJobs) {
                  runningJob.setStatus(BatchStatus.FAILED);
                  runningJob.setEndTime(new Date());
                  jobRepository.update(runningJob);
                  jobOperator.restart(runningJob.getId());
                  LOGGER.info("Job restarted: " + runningJob);
              }
          }
      } catch (Exception e) {
          LOGGER.error(e.getMessage(), e);
      }
  }
  </code></pre>
  
  <p>This works fine but with one side effect - it doesn't restart the failed job execution but creates a new execution instance. How to change this logic in order to restart the failed execution from the failed step and do not create a new execution ?</p>
  
  <p><strong>UPDATED</strong></p>
  
  <p>When I try the following code:</p>
  
  <pre><code>public void restartUncompletedJobs() {
  try {
      jobRegistry.register(new ReferenceJobFactory(documetPipelineJob));
  
      List&lt;String&gt; jobs = jobExplorer.getJobNames();
      for (String job : jobs) {
  
      Set&lt;JobExecution&gt; jobExecutions = jobExplorer.findRunningJobExecutions(job);
  
      for (JobExecution jobExecution : jobExecutions) {
          jobOperator.restart(jobExecution.getId());
      }
      }
  } catch (Exception e) {
      LOGGER.error(e.getMessage(), e);
  }
  }
  </code></pre>
  
  <p>it fails with the following exception:</p>
  
  <pre><code>2018-07-30 06:50:47.090 ERROR 1588 --- [           main] c.v.p.d.service.batch.BatchServiceImpl   : Illegal state (only happens on a race condition): job execution already running with name=documetPipelineJob and parameters={ID=826407fa-d3bc-481a-8acb-b9643b849035, inputDir=/home/public/images, STORAGE_TYPE=LOCAL}
  
  org.springframework.batch.core.UnexpectedJobExecutionException: Illegal state (only happens on a race condition): job execution already running with name=documetPipelineJob and parameters={ID=826407fa-d3bc-481a-8acb-b9643b849035, inputDir=/home/public/images, STORAGE_TYPE=LOCAL}
      at org.springframework.batch.core.launch.support.SimpleJobOperator.restart(SimpleJobOperator.java:283) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
      at org.springframework.batch.core.launch.support.SimpleJobOperator$$FastClassBySpringCGLIB$$44ee6049.invoke(&lt;generated&gt;) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
      at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) [spring-core-5.0.6.RELEASE.jar!/:5.0.6.RELEASE]
      at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684) [spring-aop-5.0.6.RELEASE.jar!/:5.0.6.RELEASE]
      at org.springframework.batch.core.launch.support.SimpleJobOperator$$EnhancerBySpringCGLIB$$7659d4c.restart(&lt;generated&gt;) ~[spring-batch-core-4.0.1.RELEASE.jar!/:4.0.1.RELEASE]
      at com.example.pipeline.domain.service.batch.BatchServiceImpl.restartUncompletedJobs(BatchServiceImpl.java:143) ~[domain-0.0.1.jar!/:0.0.1]
  </code></pre>
  
  <p><strong>The following code creates new executions in jobstore database:</strong></p>
  
  <pre><code>public void restartUncompletedJobs() {
  try {
      jobRegistry.register(new ReferenceJobFactory(documetPipelineJob));
  
      List&lt;String&gt; jobs = jobExplorer.getJobNames();
      for (String job : jobs) {
  
      Set&lt;JobExecution&gt; jobExecutions = jobExplorer.findRunningJobExecutions(job);
  
      for (JobExecution jobExecution : jobExecutions) {
  
          jobExecution.setStatus(BatchStatus.STOPPED);
          jobExecution.setEndTime(new Date());
          jobRepository.update(jobExecution);
  
          Long jobExecutionId = jobExecution.getId();
          jobOperator.restart(jobExecutionId);
      }
      }
  } catch (Exception e) {
      LOGGER.error(e.getMessage(), e);
  }
  
  }
  </code></pre>
  
  <p>The question is - how to continue to run the old uncompleted executions without creating new ones after application restart?</p>