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

About the Author

author image
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

avatar
7 Comment threads
1 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
7 Comment authors
kepongPedrogyanendra pandeyJavaTecSatish Recent comment authors
newest oldest most voted
kepong
Guest
kepong

bravo, always lead to clean cut solution

Pedro
Guest
Pedro

Thank

gyanendra pandey
Guest
gyanendra pandey

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

JavaTec
Guest
JavaTec

Excellent as always, thank you !

Satish
Guest
Satish

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

Jushoua
Guest
Jushoua

I did it but I still has the same problem

Joshua
Guest
Joshua

it still*

Karkinos
Guest
Karkinos

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.