From 5763e72c4481512518feaaf6053c2ee5ecb3ca64 Mon Sep 17 00:00:00 2001 From: lucasward Date: Wed, 6 Feb 2008 03:44:11 +0000 Subject: [PATCH] BATCH-337:No *Instance domain objects (or their respective tables) contain a 'status'. Instead, they contain the 'last execution', which can be used to determinte the status. RestartData is also no longer necessary, as everything can be 'restored' by calling stepInstance.getLastExecution().getExecutionAttributes(). Also changed all 'ID' columns to be complete, such as 'JOB_INSTANCE_ID' rather than just 'ID'. --- .../batch/execution/job/simple/SimpleJob.java | 17 +- .../repository/SimpleJobRepository.java | 19 +- .../execution/repository/dao/JdbcJobDao.java | 75 +++++--- .../execution/repository/dao/JdbcStepDao.java | 172 ++++++++++-------- .../execution/repository/dao/JobDao.java | 13 +- .../execution/repository/dao/MapJobDao.java | 29 +++ .../execution/repository/dao/MapStepDao.java | 32 +++- .../execution/repository/dao/StepDao.java | 11 ++ .../step/simple/SimpleStepExecutor.java | 10 +- .../src/main/resources/schema-db2.sql | 19 +- .../src/main/resources/schema-derby.sql | 19 +- .../src/main/resources/schema-hsqldb.sql | 19 +- .../src/main/resources/schema-mysql.sql | 19 +- .../src/main/resources/schema-oracle10g.sql | 21 +-- .../src/main/resources/schema-postgresql.sql | 19 +- .../src/main/sql/init.sql.vpp | 21 +-- .../execution/job/simple/SimpleJobTests.java | 7 +- .../execution/launch/SimpleJobTests.java | 7 +- .../execution/repository/MockStepDao.java | 5 + .../repository/SimpleJobRepositoryTests.java | 28 ++- .../repository/dao/AbstractJobDaoTests.java | 26 ++- .../repository/dao/AbstractStepDaoTests.java | 18 +- .../dao/JdbcStepDaoPrefixTests.java | 2 +- .../repository/dao/MapJobDaoTests.java | 18 ++ .../repository/dao/MapStepDaoTests.java | 15 +- .../step/simple/SimpleStepExecutorTests.java | 4 +- .../simple/StepExecutorInterruptionTests.java | 2 +- .../batch/execution/repository/dao/init.sql | 19 +- 28 files changed, 422 insertions(+), 244 deletions(-) diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/simple/SimpleJob.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/simple/SimpleJob.java index 99ae4003d..94012c365 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/simple/SimpleJob.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/simple/SimpleJob.java @@ -58,6 +58,7 @@ public class SimpleJob extends JobSupport { public void execute(JobExecution execution) throws BatchCriticalException { JobInstance jobInstance = execution.getJobInstance(); + jobInstance.setLastExecution(execution); updateStatus(execution, BatchStatus.STARTING); List stepInstances = jobInstance.getStepInstances(); @@ -115,10 +116,9 @@ public class SimpleJob extends JobSupport { } private void updateStatus(JobExecution jobExecution, BatchStatus status) { - JobInstance job = jobExecution.getJobInstance(); + JobInstance jobIntance = jobExecution.getJobInstance(); jobExecution.setStatus(status); - job.setStatus(status); - jobRepository.update(job); + jobRepository.update(jobIntance); jobRepository.saveOrUpdate(jobExecution); } @@ -128,7 +128,16 @@ public class SimpleJob extends JobSupport { */ private boolean shouldStart(StepInstance stepInstance, Step step) { - if (stepInstance.getStatus() == BatchStatus.COMPLETED && step.isAllowStartIfComplete() == false) { + BatchStatus stepStatus; + //if the last execution is null, the step has never been executed. + if(stepInstance.getLastExecution() == null){ + stepStatus = BatchStatus.STARTING; + } + else{ + stepStatus = stepInstance.getLastExecution().getStatus(); + } + + if (stepStatus== BatchStatus.COMPLETED && step.isAllowStartIfComplete() == false) { // step is complete, false should be returned, indicating that the // step should not be started return false; diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/SimpleJobRepository.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/SimpleJobRepository.java index ca678e1b2..966918283 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/SimpleJobRepository.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/SimpleJobRepository.java @@ -303,10 +303,6 @@ public class SimpleJobRepository implements JobRepository { while (i.hasNext()) { Step step = (Step) i.next(); StepInstance stepInstance = stepDao.createStep(job, step.getName()); - // Ensure valid restart data is being returned. - if (stepInstance.getExecutionAttributes() == null || stepInstance.getExecutionAttributes() == null) { - stepInstance.setExecutionAttributes(new ExecutionAttributes()); - } stepInstances.add(stepInstance); } @@ -322,15 +318,16 @@ public class SimpleJobRepository implements JobRepository { while (i.hasNext()) { Step stepConfiguration = (Step) i.next(); - StepInstance step = stepDao.findStep(job, stepConfiguration.getName()); - if (step != null) { + StepInstance stepInstance = stepDao.findStep(job, stepConfiguration.getName()); + if (stepInstance != null) { - step.setStepExecutionCount(stepDao.getStepExecutionCount(step)); - // Ensure valid restart data is being returned. - if (step.getExecutionAttributes() == null || step.getExecutionAttributes() == null) { - step.setExecutionAttributes(new ExecutionAttributes()); + if(stepInstance.getLastExecution() != null){ + ExecutionAttributes executionAttributes = stepDao.findExecutionAttributes( + stepInstance.getLastExecution().getId()); + stepInstance.getLastExecution().setExecutionAttributes(executionAttributes); } - stepInstances.add(step); + stepInstance.setStepExecutionCount(stepDao.getStepExecutionCount(stepInstance)); + stepInstances.add(stepInstance); } } return stepInstances; diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobDao.java index 449b22d4e..61f443cef 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobDao.java @@ -34,6 +34,7 @@ import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.repository.NoSuchBatchDomainObjectException; import org.springframework.batch.repeat.ExitStatus; import org.springframework.beans.factory.InitializingBean; +import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; @@ -54,13 +55,13 @@ import org.springframework.util.StringUtils; */ public class JdbcJobDao implements JobDao, InitializingBean { - private static final String CHECK_JOB_EXECUTION_EXISTS = "SELECT COUNT(*) FROM %PREFIX%JOB_EXECUTION WHERE ID=?"; + private static final String CHECK_JOB_EXECUTION_EXISTS = "SELECT COUNT(*) FROM %PREFIX%JOB_EXECUTION WHERE JOB_EXECUTION_ID = ?"; // Job SQL statements - private static final String CREATE_JOB = "INSERT into %PREFIX%JOB_INSTANCE(ID, JOB_NAME, JOB_KEY)" + private static final String CREATE_JOB = "INSERT into %PREFIX%JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY)" + " values (?, ?, ?)"; - private static final String CREATE_JOB_PARAMETERS = "INSERT into %PREFIX%JOB_INSTANCE_PARAMS(JOB_INSTANCE_ID, KEY_NAME, TYPE_CD, " + + private static final String CREATE_JOB_PARAMETERS = "INSERT into %PREFIX%JOB_PARAMS(JOB_INSTANCE_ID, KEY_NAME, TYPE_CD, " + "STRING_VAL, DATE_VAL, LONG_VAL) values (?, ?, ?, ?, ?, ?)"; /** @@ -70,21 +71,21 @@ public class JdbcJobDao implements JobDao, InitializingBean { private static final int EXIT_MESSAGE_LENGTH = 250; - private static final String FIND_JOBS = "SELECT ID, STATUS from %PREFIX%JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?"; + private static final String FIND_JOBS = "SELECT JOB_INSTANCE_ID, LAST_JOB_EXECUTION_ID from %PREFIX%JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?"; - private static final String GET_JOB_EXECUTION_COUNT = "SELECT count(ID) from %PREFIX%JOB_EXECUTION " + private static final String GET_JOB_EXECUTION_COUNT = "SELECT count(JOB_EXECUTION_ID) from %PREFIX%JOB_EXECUTION " + "where JOB_INSTANCE_ID = ?"; protected static final Log logger = LogFactory.getLog(JdbcJobDao.class); - private static final String SAVE_JOB_EXECUTION = "INSERT into %PREFIX%JOB_EXECUTION(ID, JOB_INSTANCE_ID, START_TIME, " + private static final String SAVE_JOB_EXECUTION = "INSERT into %PREFIX%JOB_EXECUTION(JOB_EXECUTION_ID, JOB_INSTANCE_ID, START_TIME, " + "END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE) values (?, ?, ?, ?, ?, ?, ?, ?)"; - private static final String UPDATE_JOB = "UPDATE %PREFIX%JOB_INSTANCE set STATUS = ? where ID = ?"; + private static final String UPDATE_JOB = "UPDATE %PREFIX%JOB_INSTANCE set LAST_JOB_EXECUTION_ID = ? where JOB_INSTANCE_ID = ?"; // Job Execution SqlStatements private static final String UPDATE_JOB_EXECUTION = "UPDATE %PREFIX%JOB_EXECUTION set START_TIME = ?, END_TIME = ?, " - + " STATUS = ?, CONTINUABLE = ?, EXIT_CODE = ?, EXIT_MESSAGE = ? where ID = ?"; + + " STATUS = ?, CONTINUABLE = ?, EXIT_CODE = ?, EXIT_MESSAGE = ? where JOB_EXECUTION_ID = ?"; private JdbcOperations jdbcTemplate; @@ -156,6 +157,29 @@ public class JdbcJobDao implements JobDao, InitializingBean { getQuery(JobExecutionRowMapper.FIND_JOB_EXECUTIONS), new Object[] { job.getId() }, new JobExecutionRowMapper(job)); } + + public JobExecution getJobExecution(Long jobExecutionId) { + + Assert.notNull(jobExecutionId, "Job Execution id must not be null."); + + List executions = jdbcTemplate.query( + getQuery(JobExecutionRowMapper.GET_JOB_EXECUTION), + new Object[] { jobExecutionId }, new JobExecutionRowMapper(null)); + + JobExecution jobExecution; + if(executions.size() == 1){ + jobExecution = (JobExecution)executions.get(0); + } + else if(executions.size() == 0){ + jobExecution = null; + } + else{ + throw new IncorrectResultSizeDataAccessException("Only one JobExecution may exist for given id: [" + + jobExecutionId + "]", 1, executions.size()); + } + + return jobExecution; + } /** * The job table is queried for any jobs that match the @@ -176,10 +200,14 @@ public class JdbcJobDao implements JobDao, InitializingBean { RowMapper rowMapper = new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { - JobInstance job = new JobInstance(new Long(rs.getLong(1)), jobParameters); - job.setStatus(BatchStatus.getStatus(rs.getString(2))); - - return job; + JobInstance jobInstance = new JobInstance(new Long(rs.getLong(1)), jobParameters); + long lastExecutionId = rs.getLong(2); + JobExecution lastExecution = getJobExecution(new Long(lastExecutionId)); + if(lastExecution != null){ + lastExecution.setJobInstance(jobInstance); + } + jobInstance.setLastExecution(lastExecution); + return jobInstance; } }; @@ -413,16 +441,15 @@ public class JdbcJobDao implements JobDao, InitializingBean { * @throws IllegalArgumentException * if Job, Job.status, or job.id is null */ - public void update(JobInstance job) { + public void update(JobInstance jobInstance) { - Assert.notNull(job, "Job Cannot be Null"); - Assert.notNull(job.getStatus(), "Job Status cannot be Null"); - Assert.notNull(job.getId(), "Job ID cannot be null"); - - Object[] parameters = new Object[] { job.getStatus().toString(), - job.getId() }; + Assert.notNull(jobInstance, "Job Cannot be Null"); + Assert.notNull(jobInstance.getId(), "Job ID cannot be null"); + + Long lastExecutionId = jobInstance.getLastExecution() == null ? null : jobInstance.getLastExecution().getId(); + Object[] parameters = new Object[] { lastExecutionId, jobInstance.getId() }; jdbcTemplate.update(getUpdateJobQuery(), parameters, new int[] { - Types.VARCHAR, Types.INTEGER}); + Types.INTEGER, Types.INTEGER}); } /* @@ -450,11 +477,11 @@ public class JdbcJobDao implements JobDao, InitializingBean { */ public static class JobExecutionRowMapper implements RowMapper { - public static final String FIND_JOB_EXECUTIONS = "SELECT ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%JOB_EXECUTION" + public static final String FIND_JOB_EXECUTIONS = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%JOB_EXECUTION" + " where JOB_INSTANCE_ID = ?"; - public static final String GET_JOB_EXECUTION = "SELECT ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%JOB_EXECUTION" - + " where ID = ?"; + public static final String GET_JOB_EXECUTION = "SELECT JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%JOB_EXECUTION" + + " where JOB_EXECUTION_ID = ?"; private JobInstance job; @@ -507,6 +534,4 @@ public class JdbcJobDao implements JobDao, InitializingBean { return null; } } - - } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepDao.java index 2c5851e75..22e681754 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepDao.java @@ -23,7 +23,6 @@ import java.sql.SQLException; import java.sql.Types; import java.util.Iterator; import java.util.List; -import java.util.Properties; import java.util.Map.Entry; import org.apache.commons.lang.SerializationUtils; @@ -75,43 +74,46 @@ import org.springframework.util.StringUtils; */ public class JdbcStepDao implements StepDao, InitializingBean { - private static final String CREATE_STEP = "INSERT into %PREFIX%STEP_INSTANCE(ID, JOB_INSTANCE_ID, STEP_NAME) values (?, ?, ?)"; + private static final String CREATE_STEP = "INSERT into %PREFIX%STEP_INSTANCE(STEP_INSTANCE_ID, JOB_INSTANCE_ID, STEP_NAME) values (?, ?, ?)"; private static final int EXIT_MESSAGE_LENGTH = 250; - private static final String FIND_STEP = "SELECT ID, STATUS, RESTART_DATA from %PREFIX%STEP_INSTANCE where JOB_INSTANCE_ID = ? " + private static final String FIND_STEP = "SELECT STEP_INSTANCE_ID, LAST_STEP_EXECUTION_ID from %PREFIX%STEP_INSTANCE where JOB_INSTANCE_ID = ? " + "and STEP_NAME = ?"; - private static final String FIND_STEP_EXECUTIONS = "SELECT ID, JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, COMMIT_COUNT," + private static final String FIND_STEP_EXECUTIONS = "SELECT STEP_EXECUTION_ID, JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, COMMIT_COUNT," + " TASK_COUNT, TASK_STATISTICS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%STEP_EXECUTION where STEP_INSTANCE_ID = ?"; + private static final String GET_STEP_EXECUTION = "SELECT STEP_EXECUTION_ID, JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, COMMIT_COUNT," + + " TASK_COUNT, TASK_STATISTICS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%STEP_EXECUTION where STEP_EXECUTION_ID = ?"; + // Step SQL statements - private static final String FIND_STEPS = "SELECT ID, STEP_NAME, STATUS, RESTART_DATA from %PREFIX%STEP_INSTANCE where JOB_INSTANCE_ID = ?"; + private static final String FIND_STEPS = "SELECT STEP_INSTANCE_ID, LAST_STEP_EXECUTION_ID, STEP_NAME from %PREFIX%STEP_INSTANCE where JOB_INSTANCE_ID = ?"; - private static final String GET_STEP_EXECUTION_COUNT = "SELECT count(ID) from %PREFIX%STEP_EXECUTION where " + private static final String GET_STEP_EXECUTION_COUNT = "SELECT count(STEP_EXECUTION_ID) from %PREFIX%STEP_EXECUTION where " + "STEP_INSTANCE_ID = ?"; protected static final Log logger = LogFactory.getLog(JdbcStepDao.class); // StepExecution statements - private static final String SAVE_STEP_EXECUTION = "INSERT into %PREFIX%STEP_EXECUTION(ID, VERSION, STEP_INSTANCE_ID, JOB_EXECUTION_ID, START_TIME, " + private static final String SAVE_STEP_EXECUTION = "INSERT into %PREFIX%STEP_EXECUTION(STEP_EXECUTION_ID, VERSION, STEP_INSTANCE_ID, JOB_EXECUTION_ID, START_TIME, " + "END_TIME, STATUS, COMMIT_COUNT, TASK_COUNT, TASK_STATISTICS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE) " + "values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - private static final String UPDATE_STEP = "UPDATE %PREFIX%STEP_INSTANCE set STATUS = ?, RESTART_DATA = ? where ID = ?"; + private static final String UPDATE_STEP = "UPDATE %PREFIX%STEP_INSTANCE set LAST_STEP_EXECUTION_ID = ? where STEP_INSTANCE_ID = ?"; private static final String UPDATE_STEP_EXECUTION = "UPDATE %PREFIX%STEP_EXECUTION set START_TIME = ?, END_TIME = ?, " + "STATUS = ?, COMMIT_COUNT = ?, TASK_COUNT = ?, TASK_STATISTICS = ?, CONTINUABLE = ? , EXIT_CODE = ?, " - + "EXIT_MESSAGE = ?, VERSION = ? where ID = ? and VERSION = ?"; + + "EXIT_MESSAGE = ?, VERSION = ? where STEP_EXECUTION_ID = ? and VERSION = ?"; private static final String UPDATE_STEP_EXECUTION_ATTRS = "UPDATE %PREFIX%STEP_EXECUTION_ATTRS set " + - "TYPE_CD = ?, STRING_VAL = ?, DOUBLE_VAL = ?, LONG_VAL = ?, OBJECT_VAL = ? where EXECUTION_ID = ? and KEY_NAME = ?"; + "TYPE_CD = ?, STRING_VAL = ?, DOUBLE_VAL = ?, LONG_VAL = ?, OBJECT_VAL = ? where STEP_EXECUTION_ID = ? and KEY_NAME = ?"; - private static final String INSERT_STEP_EXECUTION_ATTRS = "INSERT into %PREFIX%STEP_EXECUTION_ATTRS(EXECUTION_ID, TYPE_CD," + + private static final String INSERT_STEP_EXECUTION_ATTRS = "INSERT into %PREFIX%STEP_EXECUTION_ATTRS(STEP_EXECUTION_ID, TYPE_CD," + " KEY_NAME, STRING_VAL, DOUBLE_VAL, LONG_VAL, OBJECT_VAL) values(?,?,?,?,?,?,?)"; private static final String FIND_STEP_EXECUTION_ATTRS = "SELECT TYPE_CD, KEY_NAME, STRING_VAL, DOUBLE_VAL, LONG_VAL, OBJECT_VAL " + - "from %PREFIX%STEP_EXECUTION_ATTRS where EXECUTION_ID = ?"; + "from %PREFIX%STEP_EXECUTION_ATTRS where STEP_EXECUTION_ID = ?"; private JdbcOperations jdbcTemplate; @@ -171,25 +173,15 @@ public class JdbcStepDao implements StepDao, InitializingBean { * @throws IncorrectResultSizeDataAccessException if more than one step is * found. */ - public StepInstance findStep(JobInstance job, String stepName) { + public StepInstance findStep(JobInstance jobInstance, String stepName) { - Assert.notNull(job, "Job cannot be null."); - Assert.notNull(job.getId(), "Job ID cannot be null"); + Assert.notNull(jobInstance, "Job cannot be null."); + Assert.notNull(jobInstance.getId(), "Job ID cannot be null"); Assert.notNull(stepName, "StepName cannot be null"); - Object[] parameters = new Object[] { job.getId(), stepName }; + Object[] parameters = new Object[] { jobInstance.getId(), stepName }; - RowMapper rowMapper = new RowMapper() { - - public Object mapRow(ResultSet rs, int rowNum) throws SQLException { - - StepInstance step = new StepInstance(new Long(rs.getLong(1))); - step.setStatus(BatchStatus.getStatus(rs.getString(2))); - step.setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties(rs.getString(3)))); - return step; - } - - }; + RowMapper rowMapper = new StepInstanceRowMapper(jobInstance, stepName); List steps = jdbcTemplate.query(getFindStepQuery(), parameters, rowMapper); @@ -206,7 +198,7 @@ public class JdbcStepDao implements StepDao, InitializingBean { // never be two steps with the same name and JOB_INSTANCE_ID due to database // constraints. throw new IncorrectResultSizeDataAccessException("Step Invalid, multiple steps found for StepName:" - + stepName + " and JobId:" + job.getId(), 1, steps.size()); + + stepName + " and JobId:" + jobInstance.getId(), 1, steps.size()); } } @@ -223,28 +215,32 @@ public class JdbcStepDao implements StepDao, InitializingBean { Assert.notNull(step, "Step cannot be null."); Assert.notNull(step.getId(), "Step id cannot be null."); - RowMapper rowMapper = new RowMapper() { - public Object mapRow(ResultSet rs, int rowNum) throws SQLException { - - JobExecution jobExecution = (JobExecution) jdbcTemplate.queryForObject( - getQuery(JobExecutionRowMapper.GET_JOB_EXECUTION), new Object[] { new Long(rs.getLong(2)) }, - new JobExecutionRowMapper(step.getJobInstance())); - StepExecution stepExecution = new StepExecution(step, jobExecution, new Long(rs.getLong(1))); - stepExecution.setStartTime(rs.getTimestamp(3)); - stepExecution.setEndTime(rs.getTimestamp(4)); - stepExecution.setStatus(BatchStatus.getStatus(rs.getString(5))); - stepExecution.setCommitCount(rs.getInt(6)); - stepExecution.setTaskCount(rs.getInt(7)); - stepExecution.setExecutionAttributes(new ExecutionAttributes(PropertiesConverter - .stringToProperties(rs.getString(8)))); - stepExecution.setExitStatus(new ExitStatus("Y".equals(rs.getString(9)), rs.getString(10), rs - .getString(11))); - return stepExecution; - } - }; + RowMapper rowMapper = new StepExecutionRowMapper(step); return jdbcTemplate.query(getFindStepExecutionsQuery(), new Object[] { step.getId() }, rowMapper); + } + + public StepExecution getStepExecution(Long stepExecutionId, StepInstance stepInstance) { + + Assert.notNull(stepExecutionId, "Step Execution id must not be null"); + RowMapper rowMapper = new StepExecutionRowMapper(stepInstance); + + List executions = jdbcTemplate.query(getQuery(GET_STEP_EXECUTION), new Object[] { stepExecutionId }, rowMapper); + + StepExecution stepExecution; + if(executions.size() == 1){ + stepExecution = (StepExecution)executions.get(0); + } + else if(executions.size() == 0){ + stepExecution = null; + } + else{ + throw new IncorrectResultSizeDataAccessException("Only one StepExecution may exist for given id: [" + + stepExecutionId + "]", 1, executions.size()); + } + + return stepExecution; } /* @@ -405,25 +401,13 @@ public class JdbcStepDao implements StepDao, InitializingBean { * * @throws IllegalArgumentException if jobId is null. */ - public List findSteps(final JobInstance job) { + public List findSteps(final JobInstance jobInstance) { - Assert.notNull(job, "Job cannot be null."); + Assert.notNull(jobInstance, "Job cannot be null."); - Object[] parameters = new Object[] { job.getId() }; + Object[] parameters = new Object[] { jobInstance.getId() }; - RowMapper rowMapper = new RowMapper() { - - public Object mapRow(ResultSet rs, int rowNum) throws SQLException { - - StepInstance step = new StepInstance(job, rs.getString(2), new Long(rs.getLong(1))); - String status = rs.getString(3); - step.setStatus(BatchStatus.getStatus(status)); - step - .setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties(rs - .getString(3)))); - return step; - } - }; + RowMapper rowMapper = new StepInstanceRowMapper(jobInstance, null); return jdbcTemplate.query(getFindStepsQuery(), parameters, rowMapper); } @@ -632,17 +616,9 @@ public class JdbcStepDao implements StepDao, InitializingBean { public void update(final StepInstance step) { Assert.notNull(step, "Step cannot be null."); - Assert.notNull(step.getStatus(), "Step status cannot be null."); Assert.notNull(step.getId(), "Step Id cannot be null."); - Properties restartProps = null; - ExecutionAttributes executionAttributes = step.getExecutionAttributes(); - if (executionAttributes != null) { - restartProps = executionAttributes.getProperties(); - } - - Object[] parameters = new Object[] { step.getStatus().toString(), - PropertiesConverter.propertiesToString(restartProps), step.getId() }; + Object[] parameters = new Object[] { step.getLastExecution().getId(), step.getId() }; jdbcTemplate.update(getUpdateStepQuery(), parameters); } @@ -698,5 +674,57 @@ public class JdbcStepDao implements StepDao, InitializingBean { return null; } } + + private class StepExecutionRowMapper implements RowMapper{ + + private final StepInstance stepInstance; + + public StepExecutionRowMapper(StepInstance stepInstance) { + this.stepInstance = stepInstance; + } + + public Object mapRow(ResultSet rs, int rowNum) throws SQLException { + + JobExecution jobExecution = (JobExecution) jdbcTemplate.queryForObject( + getQuery(JobExecutionRowMapper.GET_JOB_EXECUTION), new Object[] { new Long(rs.getLong(2)) }, + new JobExecutionRowMapper(stepInstance.getJobInstance())); + StepExecution stepExecution = new StepExecution(stepInstance, jobExecution, new Long(rs.getLong(1))); + stepExecution.setStartTime(rs.getTimestamp(3)); + stepExecution.setEndTime(rs.getTimestamp(4)); + stepExecution.setStatus(BatchStatus.getStatus(rs.getString(5))); + stepExecution.setCommitCount(rs.getInt(6)); + stepExecution.setTaskCount(rs.getInt(7)); + stepExecution.setExecutionAttributes(new ExecutionAttributes(PropertiesConverter + .stringToProperties(rs.getString(8)))); + stepExecution.setExitStatus(new ExitStatus("Y".equals(rs.getString(9)), rs.getString(10), rs + .getString(11))); + return stepExecution; + } + + } + + private class StepInstanceRowMapper implements RowMapper{ + + private final JobInstance jobInstance; + private String stepName; + + public StepInstanceRowMapper(JobInstance jobInstance, String stepName) { + this.jobInstance = jobInstance; + this.stepName = stepName; + } + + public Object mapRow(ResultSet rs, int rowNum) throws SQLException { + + if(stepName == null){ + stepName = rs.getString(3); + } + StepInstance stepInstance = new StepInstance(jobInstance, stepName, new Long(rs.getLong(1))); + StepExecution lastExecution = getStepExecution(new Long(rs.getLong(2)), stepInstance); + stepInstance.setLastExecution(lastExecution); + return stepInstance; + } + + + } } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobDao.java index 49b0306a7..07ead726b 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobDao.java @@ -21,6 +21,7 @@ import java.util.List; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.JobParameters; +import org.springframework.dao.IncorrectResultSizeDataAccessException; /** * Data Access Object for jobs. @@ -94,5 +95,15 @@ public interface JobDao { * @param job * @return list of jobExecutions. */ - public List findJobExecutions(JobInstance job); + public List findJobExecutions(JobInstance jobInstance); + + /** + * Given an id, return the matching JobExecution. + * + * @param jobExecutionId - id of the execution to be returned. + * @return {@link JobExecution} matching the id. + * @throws {@link IncorrectResultSizeDataAccessException} if + * more than one execution is found for the given id. + */ + public JobExecution getJobExecution(Long jobExecutionId); } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapJobDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapJobDao.java index 927581f87..291b19316 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapJobDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapJobDao.java @@ -21,12 +21,14 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Map.Entry; import org.springframework.batch.core.domain.JobSupport; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; +import org.springframework.dao.IncorrectResultSizeDataAccessException; public class MapJobDao implements JobDao { @@ -97,4 +99,31 @@ public class MapJobDao implements JobDao { // no-op } + public JobExecution getJobExecution(Long jobExecutionId) { + + List jobExecutions = new ArrayList(); + + for(Iterator it = executionsById.entrySet().iterator();it.hasNext();){ + Entry entry = (Entry)it.next(); + Set executions = (Set)entry.getValue(); + for(Iterator executionsIt = executions.iterator();executionsIt.hasNext();){ + JobExecution jobExecution = (JobExecution)executionsIt.next(); + if(jobExecution.getId() == jobExecutionId){ + jobExecutions.add(jobExecution); + } + } + } + + if(jobExecutions.size() == 0){ + return null; + } + else if(jobExecutions.size() == 1){ + return (JobExecution)jobExecutions.get(0); + } + else{ + throw new IncorrectResultSizeDataAccessException("Multiple JobExecutions found for given id" + , 1, jobExecutions.size()); + } + } + } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepDao.java index db869610e..981817569 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/MapStepDao.java @@ -21,12 +21,14 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Map.Entry; import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; import org.springframework.batch.item.ExecutionAttributes; import org.springframework.batch.support.transaction.TransactionAwareProxyFactory; +import org.springframework.dao.IncorrectResultSizeDataAccessException; public class MapStepDao implements StepDao { @@ -110,6 +112,35 @@ public class MapStepDao implements StepDao { return new ArrayList(executions); } } + + public StepExecution getStepExecution(Long stepExecutionId, + StepInstance stepInstance) { + + List stepExecutions = new ArrayList(); + + for(Iterator it = executionsById.entrySet().iterator();it.hasNext();){ + Entry entry = (Entry)it.next(); + Set executions = (Set)entry.getValue(); + for(Iterator executionsIt = executions.iterator();executionsIt.hasNext();){ + StepExecution stepExecution = (StepExecution)executionsIt.next(); + if(stepExecution.getId() == stepExecutionId){ + stepExecutions.add(stepExecution); + } + } + } + + if(stepExecutions.size() == 0){ + return null; + } + else if(stepExecutions.size() == 1){ + return (StepExecution)stepExecutions.get(0); + } + else{ + throw new IncorrectResultSizeDataAccessException("Multiple StepExecutions found for given id" + , 1, stepExecutions.size()); + } + } + public void update(StepInstance step) { // no-op @@ -130,6 +161,5 @@ public class MapStepDao implements StepDao { public void update(Long executionId, ExecutionAttributes executionAttributes) { } - } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/StepDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/StepDao.java index 0bdeebe0b..23d322ae8 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/StepDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/StepDao.java @@ -22,6 +22,7 @@ import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; import org.springframework.batch.item.ExecutionAttributes; +import org.springframework.dao.IncorrectResultSizeDataAccessException; /** * Data access object for steps. @@ -103,6 +104,16 @@ public interface StepDao { */ public List findStepExecutions(StepInstance step); + /** + * Return a StepExecution for the given id. + * + * @param stepExecutionId + * @return {@link StepExecution} for the provided id. + * @throws {@link IncorrectResultSizeDataAccessException} if more + * than one execution is found. + */ + public StepExecution getStepExecution(Long stepExecutionId, StepInstance stepInstance); + /** * Find all {@link ExecutionAttributes} for the given execution id. * diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java index 9259b3c3d..c86df76cd 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java @@ -172,13 +172,15 @@ public class SimpleStepExecutor { final boolean saveExecutionAttributes = step.isSaveExecutionAttributes(); - if (saveExecutionAttributes && isRestart) { - stepContext.restoreFrom(stepInstance.getExecutionAttributes()); + if (saveExecutionAttributes && isRestart && stepInstance.getLastExecution() != null) { + stepExecution.setExecutionAttributes(stepInstance.getLastExecution().getExecutionAttributes()); + stepContext.restoreFrom(stepExecution.getExecutionAttributes()); } try { stepExecution.setStartTime(new Date(System.currentTimeMillis())); + stepInstance.setLastExecution(stepExecution); updateStatus(stepExecution, BatchStatus.STARTED); status = stepOperations.iterate(new RepeatCallback() { @@ -220,8 +222,7 @@ public class SimpleStepExecutor { stepExecution.apply(contribution); if (saveExecutionAttributes) { - stepInstance.setExecutionAttributes(stepContext.getExecutionAttributes()); - jobRepository.update(stepInstance); + stepExecution.setExecutionAttributes(stepContext.getExecutionAttributes()); } jobRepository.saveOrUpdate(stepExecution); @@ -300,7 +301,6 @@ public class SimpleStepExecutor { private void updateStatus(StepExecution stepExecution, BatchStatus status) { StepInstance step = stepExecution.getStep(); stepExecution.setStatus(status); - step.setStatus(status); jobRepository.update(step); jobRepository.saveOrUpdate(stepExecution); } diff --git a/spring-batch-execution/src/main/resources/schema-db2.sql b/spring-batch-execution/src/main/resources/schema-db2.sql index 7c324321a..931c3fe81 100644 --- a/spring-batch-execution/src/main/resources/schema-db2.sql +++ b/spring-batch-execution/src/main/resources/schema-db2.sql @@ -13,14 +13,14 @@ DROP SEQUENCE BATCH_JOB_SEQ ; -- Autogenerated: do not edit this file CREATE TABLE BATCH_JOB_INSTANCE ( - ID BIGINT PRIMARY KEY , + JOB_INSTANCE_ID BIGINT PRIMARY KEY , VERSION BIGINT, JOB_NAME VARCHAR(100) NOT NULL , JOB_KEY VARCHAR(250) , - STATUS VARCHAR(10) ); + LAST_JOB_EXECUTION_ID BIGINT ); CREATE TABLE BATCH_JOB_EXECUTION ( - ID BIGINT PRIMARY KEY , + JOB_EXECUTION_ID BIGINT PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, START_TIME TIMESTAMP NOT NULL , @@ -30,7 +30,7 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500)); -CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( +CREATE TABLE BATCH_JOB_PARAMS ( JOB_INSTANCE_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , @@ -39,15 +39,14 @@ CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( LONG_VAL BIGINT ); CREATE TABLE BATCH_STEP_INSTANCE ( - ID BIGINT PRIMARY KEY , + STEP_INSTANCE_ID BIGINT PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, - STATUS VARCHAR(10), - RESTART_DATA VARCHAR(2500)); - + LAST_STEP_EXECUTION_ID BIGINT); + CREATE TABLE BATCH_STEP_EXECUTION ( - ID BIGINT PRIMARY KEY , + STEP_EXECUTION_ID BIGINT PRIMARY KEY , VERSION BIGINT NOT NULL, STEP_INSTANCE_ID BIGINT NOT NULL, JOB_EXECUTION_ID BIGINT NOT NULL, @@ -62,7 +61,7 @@ CREATE TABLE BATCH_STEP_EXECUTION ( EXIT_MESSAGE VARCHAR(2500)); CREATE TABLE BATCH_STEP_EXECUTION_ATTRS ( - EXECUTION_ID BIGINT NOT NULL , + STEP_EXECUTION_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , diff --git a/spring-batch-execution/src/main/resources/schema-derby.sql b/spring-batch-execution/src/main/resources/schema-derby.sql index 46aa7359d..bccb55fb5 100644 --- a/spring-batch-execution/src/main/resources/schema-derby.sql +++ b/spring-batch-execution/src/main/resources/schema-derby.sql @@ -13,14 +13,14 @@ DROP TABLE BATCH_JOB_SEQ ; -- Autogenerated: do not edit this file CREATE TABLE BATCH_JOB_INSTANCE ( - ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, + JOB_INSTANCE_ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, VERSION BIGINT, JOB_NAME VARCHAR(100) NOT NULL , JOB_KEY VARCHAR(250) , - STATUS VARCHAR(10) ); + LAST_JOB_EXECUTION_ID BIGINT ); CREATE TABLE BATCH_JOB_EXECUTION ( - ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, + JOB_EXECUTION_ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, START_TIME TIMESTAMP NOT NULL , @@ -30,7 +30,7 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500)); -CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( +CREATE TABLE BATCH_JOB_PARAMS ( JOB_INSTANCE_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , @@ -39,15 +39,14 @@ CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( LONG_VAL BIGINT ); CREATE TABLE BATCH_STEP_INSTANCE ( - ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, + STEP_INSTANCE_ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, - STATUS VARCHAR(10), - RESTART_DATA VARCHAR(2500)); - + LAST_STEP_EXECUTION_ID BIGINT); + CREATE TABLE BATCH_STEP_EXECUTION ( - ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, + STEP_EXECUTION_ID BIGINT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, VERSION BIGINT NOT NULL, STEP_INSTANCE_ID BIGINT NOT NULL, JOB_EXECUTION_ID BIGINT NOT NULL, @@ -62,7 +61,7 @@ CREATE TABLE BATCH_STEP_EXECUTION ( EXIT_MESSAGE VARCHAR(2500)); CREATE TABLE BATCH_STEP_EXECUTION_ATTRS ( - EXECUTION_ID BIGINT NOT NULL , + STEP_EXECUTION_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , diff --git a/spring-batch-execution/src/main/resources/schema-hsqldb.sql b/spring-batch-execution/src/main/resources/schema-hsqldb.sql index f0a7379cf..aa4097caf 100644 --- a/spring-batch-execution/src/main/resources/schema-hsqldb.sql +++ b/spring-batch-execution/src/main/resources/schema-hsqldb.sql @@ -13,14 +13,14 @@ DROP TABLE BATCH_JOB_SEQ IF EXISTS; -- Autogenerated: do not edit this file CREATE TABLE BATCH_JOB_INSTANCE ( - ID BIGINT IDENTITY PRIMARY KEY , + JOB_INSTANCE_ID BIGINT IDENTITY PRIMARY KEY , VERSION BIGINT, JOB_NAME VARCHAR(100) NOT NULL , JOB_KEY VARCHAR(250) , - STATUS VARCHAR(10) ); + LAST_JOB_EXECUTION_ID BIGINT ); CREATE TABLE BATCH_JOB_EXECUTION ( - ID BIGINT IDENTITY PRIMARY KEY , + JOB_EXECUTION_ID BIGINT IDENTITY PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, START_TIME TIMESTAMP NOT NULL , @@ -30,7 +30,7 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500)); -CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( +CREATE TABLE BATCH_JOB_PARAMS ( JOB_INSTANCE_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , @@ -39,15 +39,14 @@ CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( LONG_VAL BIGINT ); CREATE TABLE BATCH_STEP_INSTANCE ( - ID BIGINT IDENTITY PRIMARY KEY , + STEP_INSTANCE_ID BIGINT IDENTITY PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, - STATUS VARCHAR(10), - RESTART_DATA VARCHAR(2500)); - + LAST_STEP_EXECUTION_ID BIGINT); + CREATE TABLE BATCH_STEP_EXECUTION ( - ID BIGINT IDENTITY PRIMARY KEY , + STEP_EXECUTION_ID BIGINT IDENTITY PRIMARY KEY , VERSION BIGINT NOT NULL, STEP_INSTANCE_ID BIGINT NOT NULL, JOB_EXECUTION_ID BIGINT NOT NULL, @@ -62,7 +61,7 @@ CREATE TABLE BATCH_STEP_EXECUTION ( EXIT_MESSAGE VARCHAR(2500)); CREATE TABLE BATCH_STEP_EXECUTION_ATTRS ( - EXECUTION_ID BIGINT NOT NULL , + STEP_EXECUTION_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , diff --git a/spring-batch-execution/src/main/resources/schema-mysql.sql b/spring-batch-execution/src/main/resources/schema-mysql.sql index 239ccd5c5..c1f96ef69 100644 --- a/spring-batch-execution/src/main/resources/schema-mysql.sql +++ b/spring-batch-execution/src/main/resources/schema-mysql.sql @@ -13,14 +13,14 @@ DROP TABLE IF EXISTS BATCH_JOB_SEQ ; -- Autogenerated: do not edit this file CREATE TABLE BATCH_JOB_INSTANCE ( - ID BIGINT unsigned PRIMARY KEY , + JOB_INSTANCE_ID BIGINT unsigned PRIMARY KEY , VERSION BIGINT, JOB_NAME VARCHAR(100) NOT NULL , JOB_KEY VARCHAR(250) , - STATUS VARCHAR(10) ); + LAST_JOB_EXECUTION_ID BIGINT ); CREATE TABLE BATCH_JOB_EXECUTION ( - ID BIGINT unsigned PRIMARY KEY , + JOB_EXECUTION_ID BIGINT unsigned PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, START_TIME TIMESTAMP NOT NULL , @@ -30,7 +30,7 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500)); -CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( +CREATE TABLE BATCH_JOB_PARAMS ( JOB_INSTANCE_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , @@ -39,15 +39,14 @@ CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( LONG_VAL BIGINT ); CREATE TABLE BATCH_STEP_INSTANCE ( - ID BIGINT unsigned PRIMARY KEY , + STEP_INSTANCE_ID BIGINT unsigned PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, - STATUS VARCHAR(10), - RESTART_DATA VARCHAR(2500)); - + LAST_STEP_EXECUTION_ID BIGINT); + CREATE TABLE BATCH_STEP_EXECUTION ( - ID BIGINT unsigned PRIMARY KEY , + STEP_EXECUTION_ID BIGINT unsigned PRIMARY KEY , VERSION BIGINT NOT NULL, STEP_INSTANCE_ID BIGINT NOT NULL, JOB_EXECUTION_ID BIGINT NOT NULL, @@ -62,7 +61,7 @@ CREATE TABLE BATCH_STEP_EXECUTION ( EXIT_MESSAGE VARCHAR(2500)); CREATE TABLE BATCH_STEP_EXECUTION_ATTRS ( - EXECUTION_ID BIGINT NOT NULL , + STEP_EXECUTION_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , diff --git a/spring-batch-execution/src/main/resources/schema-oracle10g.sql b/spring-batch-execution/src/main/resources/schema-oracle10g.sql index c38de7b37..f54450b7f 100644 --- a/spring-batch-execution/src/main/resources/schema-oracle10g.sql +++ b/spring-batch-execution/src/main/resources/schema-oracle10g.sql @@ -13,14 +13,14 @@ DROP SEQUENCE BATCH_JOB_SEQ ; -- Autogenerated: do not edit this file CREATE TABLE BATCH_JOB_INSTANCE ( - ID NUMBER(38) PRIMARY KEY , + JOB_INSTANCE_ID NUMBER(38) PRIMARY KEY , VERSION NUMBER(38), JOB_NAME VARCHAR(100) NOT NULL , JOB_KEY VARCHAR(250) , - STATUS VARCHAR(10) ); + LAST_JOB_EXECUTION_ID BIGINT ); CREATE TABLE BATCH_JOB_EXECUTION ( - ID NUMBER(38) PRIMARY KEY , + JOB_EXECUTION_ID NUMBER(38) PRIMARY KEY , VERSION NUMBER(38), JOB_INSTANCE_ID NUMBER(38) NOT NULL, START_TIME TIMESTAMP NOT NULL , @@ -30,8 +30,8 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500)); -CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( - JOB_INSTANCE_ID BIGINT NOT NULL , +CREATE TABLE BATCH_JOB_PARAMS ( + JOB_INSTANCE_ID NUMBER(38) NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , @@ -39,15 +39,14 @@ CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( LONG_VAL NUMBER(38) ); CREATE TABLE BATCH_STEP_INSTANCE ( - ID NUMBER(38) PRIMARY KEY , + STEP_INSTANCE_ID NUMBER(38) PRIMARY KEY , VERSION NUMBER(38), JOB_INSTANCE_ID NUMBER(38) NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, - STATUS VARCHAR(10), - RESTART_DATA VARCHAR(2500)); - + LAST_STEP_EXECUTION_ID BIGINT); + CREATE TABLE BATCH_STEP_EXECUTION ( - ID NUMBER(38) PRIMARY KEY , + STEP_EXECUTION_ID NUMBER(38) PRIMARY KEY , VERSION NUMBER(38) NOT NULL, STEP_INSTANCE_ID NUMBER(38) NOT NULL, JOB_EXECUTION_ID NUMBER(38) NOT NULL, @@ -62,7 +61,7 @@ CREATE TABLE BATCH_STEP_EXECUTION ( EXIT_MESSAGE VARCHAR(2500)); CREATE TABLE BATCH_STEP_EXECUTION_ATTRS ( - EXECUTION_ID NUMBER(38) NOT NULL , + STEP_EXECUTION_ID NUMBER(38) NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , diff --git a/spring-batch-execution/src/main/resources/schema-postgresql.sql b/spring-batch-execution/src/main/resources/schema-postgresql.sql index 7c324321a..931c3fe81 100644 --- a/spring-batch-execution/src/main/resources/schema-postgresql.sql +++ b/spring-batch-execution/src/main/resources/schema-postgresql.sql @@ -13,14 +13,14 @@ DROP SEQUENCE BATCH_JOB_SEQ ; -- Autogenerated: do not edit this file CREATE TABLE BATCH_JOB_INSTANCE ( - ID BIGINT PRIMARY KEY , + JOB_INSTANCE_ID BIGINT PRIMARY KEY , VERSION BIGINT, JOB_NAME VARCHAR(100) NOT NULL , JOB_KEY VARCHAR(250) , - STATUS VARCHAR(10) ); + LAST_JOB_EXECUTION_ID BIGINT ); CREATE TABLE BATCH_JOB_EXECUTION ( - ID BIGINT PRIMARY KEY , + JOB_EXECUTION_ID BIGINT PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, START_TIME TIMESTAMP NOT NULL , @@ -30,7 +30,7 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500)); -CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( +CREATE TABLE BATCH_JOB_PARAMS ( JOB_INSTANCE_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , @@ -39,15 +39,14 @@ CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( LONG_VAL BIGINT ); CREATE TABLE BATCH_STEP_INSTANCE ( - ID BIGINT PRIMARY KEY , + STEP_INSTANCE_ID BIGINT PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, - STATUS VARCHAR(10), - RESTART_DATA VARCHAR(2500)); - + LAST_STEP_EXECUTION_ID BIGINT); + CREATE TABLE BATCH_STEP_EXECUTION ( - ID BIGINT PRIMARY KEY , + STEP_EXECUTION_ID BIGINT PRIMARY KEY , VERSION BIGINT NOT NULL, STEP_INSTANCE_ID BIGINT NOT NULL, JOB_EXECUTION_ID BIGINT NOT NULL, @@ -62,7 +61,7 @@ CREATE TABLE BATCH_STEP_EXECUTION ( EXIT_MESSAGE VARCHAR(2500)); CREATE TABLE BATCH_STEP_EXECUTION_ATTRS ( - EXECUTION_ID BIGINT NOT NULL , + STEP_EXECUTION_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , diff --git a/spring-batch-execution/src/main/sql/init.sql.vpp b/spring-batch-execution/src/main/sql/init.sql.vpp index 7361c7618..f66c7890f 100644 --- a/spring-batch-execution/src/main/sql/init.sql.vpp +++ b/spring-batch-execution/src/main/sql/init.sql.vpp @@ -1,13 +1,13 @@ -- Autogenerated: do not edit this file CREATE TABLE BATCH_JOB_INSTANCE ( - ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED}, + JOB_INSTANCE_ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED}, VERSION ${BIGINT}, JOB_NAME VARCHAR(100) NOT NULL , JOB_KEY VARCHAR(250) , - STATUS VARCHAR(10) ); + LAST_JOB_EXECUTION_ID BIGINT ); CREATE TABLE BATCH_JOB_EXECUTION ( - ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED}, + JOB_EXECUTION_ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED}, VERSION ${BIGINT}, JOB_INSTANCE_ID ${BIGINT} NOT NULL, START_TIME TIMESTAMP NOT NULL , @@ -17,8 +17,8 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500)); -CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( - JOB_INSTANCE_ID BIGINT NOT NULL , +CREATE TABLE BATCH_JOB_PARAMS ( + JOB_INSTANCE_ID ${BIGINT} NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , @@ -26,15 +26,14 @@ CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( LONG_VAL ${BIGINT} ); CREATE TABLE BATCH_STEP_INSTANCE ( - ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED}, + STEP_INSTANCE_ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED}, VERSION ${BIGINT}, JOB_INSTANCE_ID ${BIGINT} NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, - STATUS VARCHAR(10), - RESTART_DATA VARCHAR(2500)); - + LAST_STEP_EXECUTION_ID BIGINT); + CREATE TABLE BATCH_STEP_EXECUTION ( - ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED}, + STEP_EXECUTION_ID ${BIGINT} $!{IDENTITY} PRIMARY KEY $!{GENERATED}, VERSION ${BIGINT} NOT NULL, STEP_INSTANCE_ID ${BIGINT} NOT NULL, JOB_EXECUTION_ID ${BIGINT} NOT NULL, @@ -49,7 +48,7 @@ CREATE TABLE BATCH_STEP_EXECUTION ( EXIT_MESSAGE VARCHAR(2500)); CREATE TABLE BATCH_STEP_EXECUTION_ATTRS ( - EXECUTION_ID ${BIGINT} NOT NULL , + STEP_EXECUTION_ID ${BIGINT} NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) , diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/simple/SimpleJobTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/simple/SimpleJobTests.java index aa013cfe1..6f26e7f5d 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/simple/SimpleJobTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/simple/SimpleJobTests.java @@ -218,8 +218,10 @@ public class SimpleJobTests extends TestCase { } public void testNoStepsExecuted() throws Exception { - step1.setStatus(BatchStatus.COMPLETED); - step2.setStatus(BatchStatus.COMPLETED); + StepExecution completedExecution = new StepExecution(null, null); + completedExecution.setStatus(BatchStatus.COMPLETED); + step1.setLastExecution(completedExecution); + step2.setLastExecution(completedExecution); job.execute(jobExecution); ExitStatus exitStatus = jobExecution.getExitStatus(); @@ -233,7 +235,6 @@ public class SimpleJobTests extends TestCase { private void checkRepository(BatchStatus status, ExitStatus exitStatus) { assertEquals(jobInstance, jobDao.findJobInstances(jobInstance.getJobName(), jobParameters).get(0)); // because map dao stores in memory, it can be checked directly - assertEquals(status, jobInstance.getStatus()); JobExecution jobExecution = (JobExecution) jobDao.findJobExecutions(jobInstance).get(0); assertEquals(jobInstance.getId(), jobExecution.getJobId()); assertEquals(status, jobExecution.getStatus()); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java index 2b0f2fad3..c318bf717 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobTests.java @@ -114,10 +114,9 @@ public class SimpleJobTests extends TestCase { JobExecution jobExecutionContext = new JobExecution(jobInstance); job.execute(jobExecutionContext); - assertEquals(BatchStatus.COMPLETED, jobInstance.getStatus()); + assertEquals(BatchStatus.COMPLETED, jobExecutionContext.getStatus()); assertEquals(3, processed.size()); assertTrue(processed.contains("foo")); - } public void testSimpleJobWithRecovery() throws Exception { @@ -155,7 +154,7 @@ public class SimpleJobTests extends TestCase { JobExecution jobExecution = repository.createJobExecution(job, new JobParameters()); job.execute(jobExecution); - assertEquals(BatchStatus.COMPLETED, jobExecution.getJobInstance().getStatus()); + assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); assertEquals(0, processed.size()); // provider should be exhausted assertEquals(null, provider.read()); @@ -185,6 +184,6 @@ public class SimpleJobTests extends TestCase { assertEquals("Foo", e.getMessage()); // expected } - assertEquals(BatchStatus.FAILED, jobExecution.getJobInstance().getStatus()); + assertEquals(BatchStatus.FAILED, jobExecution.getStatus()); } } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/MockStepDao.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/MockStepDao.java index 94d148787..cb00377ac 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/MockStepDao.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/MockStepDao.java @@ -84,4 +84,9 @@ public class MockStepDao implements StepDao { ExecutionAttributes executionAttributes) { } + public StepExecution getStepExecution(Long stepExecutionId, + StepInstance stepInstance) { + return null; + } + } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/SimpleJobRepositoryTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/SimpleJobRepositoryTests.java index 956bc5f6b..22826bafd 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/SimpleJobRepositoryTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/SimpleJobRepositoryTests.java @@ -76,6 +76,8 @@ public class SimpleJobRepositoryTests extends TestCase { StepInstance databaseStep2; List steps; + + ExecutionAttributes executionAttributes; private JobExecution jobExecution; @@ -111,11 +113,15 @@ public class SimpleJobRepositoryTests extends TestCase { }; databaseStep1 = new StepInstance(new Long(1)); + databaseStep1.setLastExecution(new StepExecution(databaseStep1, null)); databaseStep2 = new StepInstance(new Long(2)); + databaseStep2.setLastExecution(new StepExecution(databaseStep2, null)); steps = new ArrayList(); steps.add(databaseStep1); steps.add(databaseStep2); + + executionAttributes = new ExecutionAttributes(); } /* @@ -161,10 +167,14 @@ public class SimpleJobRepositoryTests extends TestCase { jobDaoControl.setReturnValue(jobs); stepDao.findStep(databaseJob, "TestStep1"); stepDaoControl.setReturnValue(databaseStep1); + stepDao.findExecutionAttributes(databaseStep1.getLastExecution().getId()); + stepDaoControl.setReturnValue(executionAttributes); stepDao.getStepExecutionCount(databaseStep1); stepDaoControl.setReturnValue(1); stepDao.findStep(databaseJob, "TestStep2"); stepDaoControl.setReturnValue(databaseStep2); + stepDao.findExecutionAttributes(databaseStep2.getLastExecution().getId()); + stepDaoControl.setReturnValue(executionAttributes); stepDao.getStepExecutionCount(databaseStep2); stepDaoControl.setReturnValue(1); stepDaoControl.replay(); @@ -233,10 +243,14 @@ public class SimpleJobRepositoryTests extends TestCase { jobDaoControl.setReturnValue(jobs); stepDao.findStep(databaseJob, "TestStep1"); stepDaoControl.setReturnValue(databaseStep1); + stepDao.findExecutionAttributes(databaseStep1.getLastExecution().getId()); + stepDaoControl.setReturnValue(executionAttributes); stepDao.getStepExecutionCount(databaseStep1); stepDaoControl.setReturnValue(1); stepDao.findStep(databaseJob, "TestStep2"); stepDaoControl.setReturnValue(databaseStep2); + stepDao.findExecutionAttributes(databaseStep2.getLastExecution().getId()); + stepDaoControl.setReturnValue(executionAttributes); stepDao.getStepExecutionCount(databaseStep2); stepDaoControl.setReturnValue(1); stepDaoControl.replay(); @@ -411,10 +425,8 @@ public class SimpleJobRepositoryTests extends TestCase { jobDao.createJobInstance(jobConfiguration.getName(), jobParameters); jobDaoControl.setReturnValue(databaseJob); stepDao.createStep(databaseJob, "TestStep1"); - databaseStep1.setExecutionAttributes(null); stepDaoControl.setReturnValue(databaseStep1); stepDao.createStep(databaseJob, "TestStep2"); - databaseStep2.setExecutionAttributes(new ExecutionAttributes()); stepDaoControl.setReturnValue(databaseStep2); jobDao.save(new JobExecution(databaseJob)); jobDaoControl.setMatcher(new ArgumentsMatcher(){ @@ -432,10 +444,8 @@ public class SimpleJobRepositoryTests extends TestCase { Iterator it = jobSteps.iterator(); StepInstance step = (StepInstance) it.next(); assertTrue(step.equals(databaseStep1)); - assertTrue(step.getExecutionAttributes().getProperties().isEmpty()); step = (StepInstance) it.next(); assertTrue(step.equals(databaseStep2)); - assertTrue(step.getExecutionAttributes().getProperties().isEmpty()); } public void testFindStepsFixesInvalidExecutionAttributes() throws Exception{ @@ -444,13 +454,15 @@ public class SimpleJobRepositoryTests extends TestCase { jobs.add(databaseJob); jobDaoControl.setReturnValue(jobs); stepDao.findStep(databaseJob, "TestStep1"); - databaseStep1.setExecutionAttributes(null); stepDaoControl.setReturnValue(databaseStep1); + stepDao.findExecutionAttributes(databaseStep1.getLastExecution().getId()); + stepDaoControl.setReturnValue(executionAttributes); stepDao.getStepExecutionCount(databaseStep1); stepDaoControl.setReturnValue(1); stepDao.findStep(databaseJob, "TestStep2"); - databaseStep2.setExecutionAttributes(new ExecutionAttributes()); stepDaoControl.setReturnValue(databaseStep2); + stepDao.findExecutionAttributes(databaseStep2.getLastExecution().getId()); + stepDaoControl.setReturnValue(executionAttributes); stepDao.getStepExecutionCount(databaseStep2); stepDaoControl.setReturnValue(1); stepDaoControl.replay(); @@ -476,9 +488,9 @@ public class SimpleJobRepositoryTests extends TestCase { Iterator it = jobSteps.iterator(); StepInstance step = (StepInstance) it.next(); assertTrue(step.equals(databaseStep1)); - assertTrue(step.getExecutionAttributes().getProperties().isEmpty()); + assertTrue(step.getLastExecution().getExecutionAttributes().isEmpty()); step = (StepInstance) it.next(); - assertTrue(step.getExecutionAttributes().getProperties().isEmpty()); + assertTrue(step.getLastExecution().getExecutionAttributes().isEmpty()); assertTrue(step.equals(databaseStep2)); } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractJobDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractJobDaoTests.java index 77fec8620..093dbbf49 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractJobDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractJobDaoTests.java @@ -80,18 +80,20 @@ public abstract class AbstractJobDaoTests extends jobExecution.setStartTime(jobExecutionStartTime); jobExecution.setStatus(BatchStatus.STARTED); jobDao.save(jobExecution); + jobInstance.setLastExecution(jobExecution); + jobDao.update(jobInstance); } public void testVersionIsNotNullForJob() throws Exception { int version = jdbcTemplate - .queryForInt("select version from BATCH_JOB_INSTANCE where ID=" + .queryForInt("select version from BATCH_JOB_INSTANCE where JOB_INSTANCE_ID=" + jobInstance.getId()); assertEquals(0, version); } public void testVersionIsNotNullForJobExecution() throws Exception { int version = jdbcTemplate - .queryForInt("select version from BATCH_JOB_EXECUTION where ID=" + .queryForInt("select version from BATCH_JOB_EXECUTION where JOB_EXECUTION_ID=" + jobExecution.getId()); assertEquals(0, version); } @@ -148,7 +150,9 @@ public abstract class AbstractJobDaoTests extends public void testUpdateJob() { // Update the returned job with a new status - jobInstance.setStatus(BatchStatus.COMPLETED); + JobExecution newExecution = new JobExecution(jobInstance); + jobDao.save(newExecution); + jobInstance.setLastExecution(newExecution); jobDao.update(jobInstance); // The job just updated should be found, with the saved status. @@ -156,7 +160,19 @@ public abstract class AbstractJobDaoTests extends assertTrue(jobs.size() == 1); JobInstance tempJob = (JobInstance) jobs.get(0); assertTrue(jobInstance.equals(tempJob)); - assertEquals(tempJob.getStatus(), BatchStatus.COMPLETED); + assertEquals(newExecution, tempJob.getLastExecution()); + } + + public void testGetJobExecution(){ + + JobExecution tempExecution = jobDao.getJobExecution(jobExecution.getId()); + assertEquals(jobExecution, tempExecution); + } + + public void testJobInstanceLastExecution(){ + //ensure the last execution id is being stored + JobExecution lastJobExecution = jobDao.getJobExecution(jobInstance.getLastExecution().getId()); + assertEquals(lastJobExecution, jobExecution); } public void testUpdateJobWithNullId() { @@ -249,7 +265,7 @@ public abstract class AbstractJobDaoTests extends jobInstance = jobDao.createJobInstance("test", jobParameters); List jobs = jdbcTemplate.queryForList( - "SELECT * FROM BATCH_JOB_INSTANCE where ID=?", new Object[] { jobInstance + "SELECT * FROM BATCH_JOB_INSTANCE where JOB_INSTANCE_ID=?", new Object[] { jobInstance .getId() }); assertEquals(1, jobs.size()); assertEquals("test", ((Map) jobs.get(0)).get("JOB_NAME")); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java index d4d3738bf..23fcfa8c2 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java @@ -95,22 +95,25 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour stepExecution.setStatus(BatchStatus.STARTED); stepExecution.setStartTime(new Date(System.currentTimeMillis())); stepDao.save(stepExecution); + step1.setLastExecution(stepExecution); + stepDao.update(step1); executionAttributes = new ExecutionAttributes(); executionAttributes.putString("1", "testString1"); executionAttributes.putString("2", "testString2"); executionAttributes.putLong("3", 3); executionAttributes.putDouble("4", 4.4); + } public void testVersionIsNotNullForStep() throws Exception { - int version = jdbcTemplate.queryForInt("select version from BATCH_STEP_INSTANCE where ID=" + step1.getId()); + int version = jdbcTemplate.queryForInt("select version from BATCH_STEP_INSTANCE where STEP_INSTANCE_ID=" + step1.getId()); assertEquals(0, version); } public void testVersionIsNotNullForStepExecution() throws Exception { - int version = jdbcTemplate.queryForInt("select version from BATCH_STEP_EXECUTION where ID=" + int version = jdbcTemplate.queryForInt("select version from BATCH_STEP_EXECUTION where STEP_EXECUTION_ID=" + stepExecution.getId()); assertEquals(0, version); } @@ -151,7 +154,6 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour public void testUpdateStepWithoutExecutionAttributes() { - step1.setStatus(BatchStatus.COMPLETED); stepDao.update(step1); StepInstance tempStep = stepDao.findStep(jobInstance, step1.getName()); assertEquals(tempStep, step1); @@ -159,15 +161,11 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour public void testUpdateStepWithExecutionAttributes() { - step1.setStatus(BatchStatus.COMPLETED); - Properties data = new Properties(); - data.setProperty("restart.key1", "restartData"); - ExecutionAttributes executionAttributes = new ExecutionAttributes(data); - step1.setExecutionAttributes(executionAttributes); - stepDao.update(step1); + stepDao.save(step1.getId(), executionAttributes); StepInstance tempStep = stepDao.findStep(jobInstance, step1.getName()); + ExecutionAttributes tempAttributes = stepDao.findExecutionAttributes(step1.getId()); assertEquals(tempStep, step1); - assertEquals(tempStep.getExecutionAttributes().getProperties().toString(), executionAttributes.getProperties().toString()); + assertEquals(executionAttributes, tempAttributes); } public void testSaveStepExecution() { diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcStepDaoPrefixTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcStepDaoPrefixTests.java index c89fd880a..93dfe02ce 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcStepDaoPrefixTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcStepDaoPrefixTests.java @@ -53,7 +53,7 @@ public class JdbcStepDaoPrefixTests extends TestCase { stepDao.setStepIncrementer(stepIncrementer); stepExecution.setId(new Long(1)); stepExecution.incrementVersion(); - step.setStatus(BatchStatus.STARTED); + step.setLastExecution(stepExecution); job.addStepInstance(step); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapJobDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapJobDaoTests.java index 35d6d3b50..9a21ba10f 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapJobDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapJobDaoTests.java @@ -73,4 +73,22 @@ public class MapJobDaoTests extends TestCase { dao.save(new JobExecution(job)); assertEquals(2, dao.getJobExecutionCount(job.getId())); } + + public void testGetJobExecution(){ + + JobInstance jobInstance = dao.createJobInstance("foo", jobParameters); + JobExecution jobExecution = new JobExecution(jobInstance); + dao.save(jobExecution); + JobExecution tempExecution = dao.getJobExecution(jobExecution.getId()); + assertEquals(jobExecution, tempExecution); + } + + public void testGetNonExistantJobExecution(){ + + JobInstance jobInstance = dao.createJobInstance("foo", jobParameters); + JobExecution jobExecution = new JobExecution(jobInstance); + dao.save(jobExecution); + assertNull(dao.getJobExecution(new Long(999999))); + + } } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepDaoTests.java index c5c3a5b90..dc3e34adc 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/MapStepDaoTests.java @@ -21,12 +21,10 @@ import java.util.Properties; import junit.framework.TestCase; -import org.springframework.batch.core.domain.BatchStatus; import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.execution.repository.dao.MapStepDao; import org.springframework.batch.item.ExecutionAttributes; public class MapStepDaoTests extends TestCase { @@ -107,16 +105,15 @@ public class MapStepDaoTests extends TestCase { public void testSaveExecutionAttributes() throws Exception { assertEquals(null, dao.getExecutionAttributes(step.getId())); - step.setStatus(BatchStatus.COMPLETED); Properties data = new Properties(); data.setProperty("restart.key1", "restartData"); ExecutionAttributes executionAttributes = new ExecutionAttributes(data); - step.setExecutionAttributes(executionAttributes); - dao.update(step); - StepInstance tempStep = dao.findStep(job, step.getName()); - assertEquals(tempStep, step); - assertEquals(tempStep.getExecutionAttributes().getProperties().toString(), - executionAttributes.getProperties().toString()); + StepExecution stepExecution = new StepExecution(step, null, null); + stepExecution.setExecutionAttributes(executionAttributes); + dao.save(stepExecution); + StepExecution tempExecution = dao.getStepExecution(stepExecution.getId(), step); + assertEquals(tempExecution, stepExecution); + assertEquals(stepExecution.getExecutionAttributes(), tempExecution.getExecutionAttributes()); } } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java index e674c696a..c4bbe95c5 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java @@ -313,9 +313,9 @@ public class SimpleStepExecutorTests extends TestCase { JobExecution jobExecutionContext = new JobExecution(jobInstance); StepExecution stepExecution = new StepExecution(step, jobExecutionContext); - stepExecution.getStep().setExecutionAttributes( + stepExecution.setExecutionAttributes( new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar"))); - + step.setLastExecution(stepExecution); stepExecutor.execute(stepExecution); assertTrue(tasklet.isRestoreFromCalled()); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java index 822411666..aa9262fe4 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java @@ -107,7 +107,7 @@ public class StepExecutorInterruptionTests extends TestCase { } assertFalse(processingThread.isAlive()); - assertEquals(BatchStatus.STOPPED, step.getStatus()); + assertEquals(BatchStatus.STOPPED, stepExecution.getStatus()); } public void testInterruptStep() throws Exception { diff --git a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/repository/dao/init.sql b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/repository/dao/init.sql index 9c34d9f6b..ab03580d8 100644 --- a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/repository/dao/init.sql +++ b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/repository/dao/init.sql @@ -1,13 +1,13 @@ -- Autogenerated: do not edit this file CREATE TABLE BATCH_JOB_INSTANCE ( - ID BIGINT IDENTITY PRIMARY KEY , + JOB_INSTANCE_ID BIGINT IDENTITY PRIMARY KEY , VERSION BIGINT, JOB_NAME VARCHAR(100) NOT NULL , JOB_KEY VARCHAR(250) , - STATUS VARCHAR(10) ); + LAST_JOB_EXECUTION_ID BIGINT ); CREATE TABLE BATCH_JOB_EXECUTION ( - ID BIGINT IDENTITY PRIMARY KEY , + JOB_EXECUTION_ID BIGINT IDENTITY PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, START_TIME TIMESTAMP NOT NULL , @@ -17,7 +17,7 @@ CREATE TABLE BATCH_JOB_EXECUTION ( EXIT_CODE VARCHAR(20), EXIT_MESSAGE VARCHAR(2500)); -CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( +CREATE TABLE BATCH_JOB_PARAMS ( JOB_INSTANCE_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , @@ -26,15 +26,14 @@ CREATE TABLE BATCH_JOB_INSTANCE_PARAMS ( LONG_VAL BIGINT ); CREATE TABLE BATCH_STEP_INSTANCE ( - ID BIGINT IDENTITY PRIMARY KEY , + STEP_INSTANCE_ID BIGINT IDENTITY PRIMARY KEY , VERSION BIGINT, JOB_INSTANCE_ID BIGINT NOT NULL, STEP_NAME VARCHAR(100) NOT NULL, - STATUS VARCHAR(10), - RESTART_DATA VARCHAR(2500)); - + LAST_STEP_EXECUTION_ID BIGINT); + CREATE TABLE BATCH_STEP_EXECUTION ( - ID BIGINT IDENTITY PRIMARY KEY , + STEP_EXECUTION_ID BIGINT IDENTITY PRIMARY KEY , VERSION BIGINT NOT NULL, STEP_INSTANCE_ID BIGINT NOT NULL, JOB_EXECUTION_ID BIGINT NOT NULL, @@ -49,7 +48,7 @@ CREATE TABLE BATCH_STEP_EXECUTION ( EXIT_MESSAGE VARCHAR(2500)); CREATE TABLE BATCH_STEP_EXECUTION_ATTRS ( - EXECUTION_ID BIGINT NOT NULL , + STEP_EXECUTION_ID BIGINT NOT NULL , TYPE_CD VARCHAR(6) NOT NULL , KEY_NAME VARCHAR(100) NOT NULL , STRING_VAL VARCHAR(250) ,