Spring Batch : A job instance already exists and is complete for parameters={}

Working with Spring Batch 2.2.0.RELEASE, and launches the job with Spring Scheduler.

CustomJobLauncher.java

package com.mkyong.batch;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CustomJobLauncher {

	@Autowired
	JobLauncher jobLauncher;

	@Autowired
	Job job;

	public void run() {

	  try {

		JobExecution execution = jobLauncher.run(job, new JobParameters());
		System.out.println("Exit Status : " + execution.getStatus());
			
	  } catch (Exception e) {
		e.printStackTrace();
	  }

	}

}
job-config.xml

  <bean id="customJobLauncher" class="com.mkyong.batch.CustomJobLauncher" />

  <task:scheduled-tasks>
	<task:scheduled ref="customJobLauncher" method="run" fixed-delay="10000" />
  </task:scheduled-tasks>

Problem

The batch job is running successful in the first time only, when it launches the second time (after 10 seconds) it prompts following error messages.


org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: 
	A job instance already exists and is complete for parameters={}.  
        If you want to run this job again, change the parameters.
	at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:126)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

Solution

Refer error message above “If you want to run this job again, change the parameters.” The formula is JobInstance = JobParameters + Job. If you do not have any parameters for JobParameters, just pass a current time as parameter to create a new JobInstance. For example,

CustomJobLauncher.java

//...

@Component
public class CustomJobLauncher {

	@Autowired
	JobLauncher jobLauncher;

	@Autowired
	Job job;

	public void run() {

	  try {
		JobParameters jobParameters = 
		  new JobParametersBuilder()
		  .addLong("time",System.currentTimeMillis()).toJobParameters();
			
		JobExecution execution = jobLauncher.run(job, jobParameters);
		System.out.println("Exit Status : " + execution.getStatus());
			
	  } catch (Exception e) {
		e.printStackTrace();
	  }

	}

}

References

  1. Spring Batch : Configuring and Running a Job
  2. How to create new job instance

mkyong

Founder of Mkyong.com, passionate Java and open-source technologies. If you enjoy my tutorials, consider making a donation to these charities.

9 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
gyanendra pandey
7 years ago

No one can give better Example than you, please continue…

Preeti
6 years ago

Thank you! As always i found a solution here

kepong
6 years ago

bravo, always lead to clean cut solution

Pedro
6 years ago

Thank

JavaTec
8 years ago

Excellent as always, thank you !

Satish
11 years ago

Hi, How to pass Values form one Job to another job

Jushoua
12 years ago

I did it but I still has the same problem

Joshua
12 years ago
Reply to  Jushoua

it still*

Karkinos
12 years ago

Mkyong, I got the answer. I just have to add property
in the bean

see: http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/item/file/FlatFileItemReader.html#setLinesToSkip(int)

Note: In my case I had to delete all tables data, commit, refresh Mysql connection, and run the job in order to see the changes in the table.