diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java index 0bb889d00..bef390357 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JdbcJobExecutionDao.java @@ -50,7 +50,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements + " STATUS = ?, CONTINUABLE = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, CREATE_TIME = ?, LAST_UPDATED = ? where JOB_EXECUTION_ID = ?"; private static final String FIND_JOB_EXECUTIONS = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED" + - " from %PREFIX%JOB_EXECUTION where JOB_INSTANCE_ID = ?"; + " from %PREFIX%JOB_EXECUTION where JOB_INSTANCE_ID = ? order by JOB_EXECUTION_ID"; private static final String GET_LAST_EXECUTION = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED " + "from %PREFIX%JOB_EXECUTION where JOB_INSTANCE_ID = ? and CREATE_TIME = (SELECT max(CREATE_TIME) from %PREFIX%JOB_EXECUTION where JOB_INSTANCE_ID = ?)"; @@ -59,7 +59,7 @@ public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements " from %PREFIX%JOB_EXECUTION where JOB_EXECUTION_ID = ?"; private static final String GET_RUNNING_EXECUTIONS = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE, CREATE_TIME, LAST_UPDATED, " + - "JOB_INSTANCE_ID from %PREFIX%JOB_EXECUTION where END_TIME is NULL"; + "JOB_INSTANCE_ID from %PREFIX%JOB_EXECUTION where END_TIME is NULL order by JOB_EXECUTION_ID"; private int exitMessageLength = DEFAULT_EXIT_MESSAGE_LENGTH; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java index d160aa4d9..214e735e7 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/JobExecutionDao.java @@ -35,15 +35,14 @@ public interface JobExecutionDao { void updateJobExecution(JobExecution jobExecution); /** - * Return all {@link JobExecution} for given {@link JobInstance}. - * - * @param jobInstance - * @return list of jobExecutions. + * Return all {@link JobExecution} for given {@link JobInstance}, sorted + * backwards by creation order (so the first element is the most recent). */ List findJobExecutions(JobInstance jobInstance); /** - * Find the last {@link JobExecution} to have been created for a given {@link JobInstance}. + * Find the last {@link JobExecution} to have been created for a given + * {@link JobInstance}. * @param jobInstance the {@link JobInstance} * @return the last {@link JobExecution} to execute for this instance */ @@ -59,10 +58,11 @@ public interface JobExecutionDao { * @return the {@link JobExecution} for given identifier. */ JobExecution getJobExecution(Long executionId); - + /** - * Because it may be possible that the status of a JobExecution is updated while running, - * the following method while synchronize only the status field. + * Because it may be possible that the status of a JobExecution is updated + * while running, the following method while synchronize only the status + * field. * * @param jobExecution to be updated. */ diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/MapJobExecutionDao.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/MapJobExecutionDao.java index 37d24a29d..5384b6fd5 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/MapJobExecutionDao.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/dao/MapJobExecutionDao.java @@ -1,6 +1,8 @@ package org.springframework.batch.core.repository.dao; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -39,6 +41,20 @@ public class MapJobExecutionDao implements JobExecutionDao { executions.add(exec); } } + Collections.sort(executions, new Comparator() { + + public int compare(JobExecution e1, JobExecution e2) { + long result = (e1.getId() - e2.getId()); + if (result > 0) { + return 1; + } else if (result < 0) { + return -1; + } else { + return 0; + } + } + + }); return executions; } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobExecutionDaoTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobExecutionDaoTests.java index bb274b5f8..9dae2f755 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobExecutionDaoTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/dao/AbstractJobExecutionDaoTests.java @@ -5,6 +5,7 @@ import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; @@ -14,6 +15,7 @@ import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.StepExecution; +import org.springframework.batch.repeat.ExitStatus; import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests; import org.springframework.transaction.annotation.Transactional; @@ -51,6 +53,8 @@ public abstract class AbstractJobExecutionDaoTests extends AbstractTransactional execution.setStartTime(new Date(System.currentTimeMillis())); execution.setLastUpdated(new Date(System.currentTimeMillis())); + execution.setExitStatus(ExitStatus.UNKNOWN); + execution.setEndTime(new Date(System.currentTimeMillis())); dao.saveJobExecution(execution); List executions = dao.findJobExecutions(jobInstance); @@ -58,6 +62,30 @@ public abstract class AbstractJobExecutionDaoTests extends AbstractTransactional assertEquals(execution, executions.get(0)); assertExecutionsAreEqual(execution, executions.get(0)); } + + /** + * Executions should be returned in the same order they were saved. + */ + @Transactional + @Test + public void testFindExecutionsOrdering() { + + List execs = new ArrayList(); + + for (int i = 0; i < 10; i++) { + JobExecution exec = new JobExecution(jobInstance); + exec.setCreateTime(new Date(i)); + execs.add(exec); + dao.saveJobExecution(exec); + } + + List retrieved = dao.findJobExecutions(jobInstance); + + for (int i = 0; i < 10; i++) { + assertExecutionsAreEqual(execs.get(i), retrieved.get(i)); + } + + } /** * Save and find a job execution.