Prajjwal Gupta
Prajjwal Gupta

Reputation: 63

A job instance already exists and is complete for parameters

Whenever I'm trying to run the job asynchronously, I'm getting this error

A job instance already exists and is complete for parameters={fileName=D:\experiment\31employeeCSVFile.csv}. If you want to run this job again, change the parameters.

Here is what I'm trying to do:

@Autowired
JobLauncher jobLauncher;

@Autowired
@Qualifier("importEmployeeJob")
Job job;

@RequestMapping("/jobLauncher")
    public ResponseEntity<String> handle() throws Exception {
        log.info("Rest request to handle()");

        Thread async = new Thread(new Runnable() {

            @Override
            public void run() {

                String fileLocation = "D:\\experiment\\31employeeCSVFile.csv";
                Map<String, JobParameter> JobParameters = new HashMap<String, JobParameter>();
                JobParameters.put("fileName", new JobParameter(fileLocation));
                try {
                    jobLauncher.run(job, new JobParameters(JobParameters));
                } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException
                        | JobParametersInvalidException e) {
                    e.printStackTrace();
                }
                log.info("success");
            }
        });
        log.info("Starting job...");
        async.start();
        return ResponseEntity.ok("Job started");
    }

Complete exception trace:

org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={fileName=D:\experiment\31employeeCSVFile.csv}. If you want to run this job again, change the parameters. at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:131) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:181) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) at com.sun.proxy.$Proxy63.createJobExecution(Unknown Source) at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) at com.sun.proxy.$Proxy68.run(Unknown Source) at com.diatoz.demo.rest.EmployeeResource$1.run(EmployeeResource.java:61) at java.lang.Thread.run(Unknown Source)

At least for the first time it should run. What am I doing wrong?
One more thing to add that if I don't use runnable then everything works perfectly fine.

Update:
Following the error message, I tried by setting one more unique job parameter (i.e. Timestamp), and it ran. But It's still mystery to me that why it is denying to run even for the first time.

Upvotes: 1

Views: 1377

Answers (1)

Mahmoud Ben Hassine
Mahmoud Ben Hassine

Reputation: 31590

You should already have a job instance with that parameter in your db (probably created in your previous tests?). With a fresh db, you should not have this error in the first run, unless two requests come at the same time and try to create a job instance with the same parameter and one of them completes before the other tries to create a job instance.. (which is very unlikely to happen).

Apart from that, you should not be manually creating threads to start jobs asynchronously. What you need to do instead is configure your job launcher with an asynchronous TaskExecutor implementation instead. For more details about that, please refer to the Running Jobs from within a Web Container section.

Upvotes: 1

Related Questions