Skip to content

Commit

Permalink
Fix job execution validation in SimpleJobRepository
Browse files Browse the repository at this point in the history
Before this commit, the logic that validates if a job
instance is complete or not was based only on the size
of previous parameters, without checking if they are
identifying or not.

This commit introduces a change that uses only
identifying job parameters to identify a job instance
and validate its previous executions.

Issue #1221
  • Loading branch information
fmbenhassine committed May 6, 2021
1 parent c3b2e26 commit a5595bf
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2020 the original author or authors.
* Copyright 2006-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,6 +21,7 @@
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
Expand Down Expand Up @@ -132,7 +133,9 @@ public JobExecution createJobExecution(String jobName, JobParameters jobParamete
+ "The last execution ended with a failure that could not be rolled back, "
+ "so it may be dangerous to proceed. Manual intervention is probably necessary.");
}
if (execution.getJobParameters().getParameters().size() > 0 && (status == BatchStatus.COMPLETED || status == BatchStatus.ABANDONED)) {
Collection<JobParameter> allJobParameters = execution.getJobParameters().getParameters().values();
long identifyingJobParametersCount = allJobParameters.stream().filter(JobParameter::isIdentifying).count();
if (identifyingJobParametersCount > 0 && (status == BatchStatus.COMPLETED || status == BatchStatus.ABANDONED)) {
throw new JobInstanceAlreadyCompleteException(
"A job instance already exists and is complete for parameters=" + jobParameters
+ ". If you want to run this job again, change the parameters.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2008-2018 the original author or authors.
* Copyright 2008-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -44,6 +44,7 @@
*
* @author Robert Kasanicky
* @author Dimitrios Liapis
* @author Mahmoud Ben Hassine
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/org/springframework/batch/core/repository/dao/sql-dao-test.xml")
Expand Down Expand Up @@ -212,4 +213,23 @@ public void testGetLastJobExecution() throws Exception {
assertEquals(stepExecution, jobExecution.getStepExecutions().iterator().next());
}

/*
* Create two job executions for the same job+parameters tuple. Should ignore
* non-identifying job parameters when identifying the job instance.
*/
@Transactional
@Test
public void testReExecuteWithSameJobParameters() throws Exception {
JobParameters jobParameters = new JobParametersBuilder()
.addString("name", "foo", false)
.toJobParameters();
JobExecution jobExecution1 = jobRepository.createJobExecution(job.getName(), jobParameters);
jobExecution1.setStatus(BatchStatus.COMPLETED);
jobExecution1.setEndTime(new Date());
jobRepository.update(jobExecution1);
JobExecution jobExecution2 = jobRepository.createJobExecution(job.getName(), jobParameters);
assertNotNull(jobExecution1);
assertNotNull(jobExecution2);
}

}

0 comments on commit a5595bf

Please sign in to comment.