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 2386b62b4..517ab37f3 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 @@ -32,6 +32,8 @@ import org.springframework.batch.core.repository.BatchRestartException; import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.execution.repository.dao.JobDao; +import org.springframework.batch.execution.repository.dao.JobExecutionDao; +import org.springframework.batch.execution.repository.dao.JobInstanceDao; import org.springframework.batch.execution.repository.dao.StepExecutionDao; import org.springframework.batch.execution.repository.dao.StepInstanceDao; import org.springframework.batch.item.ExecutionAttributes; @@ -55,7 +57,9 @@ import org.springframework.util.Assert; */ public class SimpleJobRepository implements JobRepository { - private JobDao jobDao; + private JobInstanceDao jobDao; + + private JobExecutionDao jobExecutionDao; private StepInstanceDao stepInstanceDao; @@ -68,9 +72,11 @@ public class SimpleJobRepository implements JobRepository { SimpleJobRepository() { } - public SimpleJobRepository(JobDao jobDao, StepInstanceDao stepInstanceDao, StepExecutionDao stepExecutionDao) { + public SimpleJobRepository(JobInstanceDao jobDao, JobExecutionDao jobExecutionDao, StepInstanceDao stepInstanceDao, + StepExecutionDao stepExecutionDao) { super(); this.jobDao = jobDao; + this.jobExecutionDao = jobExecutionDao; this.stepInstanceDao = stepInstanceDao; this.stepExecutionDao = stepExecutionDao; } @@ -166,11 +172,11 @@ public class SimpleJobRepository implements JobRepository { // One job was found jobInstance = (JobInstance) jobs.get(0); jobInstance.setStepInstances(findStepInstances(job.getSteps(), jobInstance)); - jobInstance.setJobExecutionCount(jobDao.getJobExecutionCount(jobInstance.getId())); + jobInstance.setJobExecutionCount(jobExecutionDao.getJobExecutionCount(jobInstance.getId())); if (jobInstance.getJobExecutionCount() > job.getStartLimit()) { throw new BatchRestartException("Restart Max exceeded for Job: " + jobInstance.toString()); } - List executions = jobDao.findJobExecutions(jobInstance); + List executions = jobExecutionDao.findJobExecutions(jobInstance); for (Iterator iterator = executions.iterator(); iterator.hasNext();) { JobExecution execution = (JobExecution) iterator.next(); if (execution.isRunning()) { @@ -219,11 +225,11 @@ public class SimpleJobRepository implements JobRepository { if (jobExecution.getId() == null) { // existing instance - jobDao.saveJobExecution(jobExecution); + jobExecutionDao.saveJobExecution(jobExecution); } else { // new execution - jobDao.updateJobExecution(jobExecution); + jobExecutionDao.updateJobExecution(jobExecution); } } 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 deleted file mode 100644 index c18e955f0..000000000 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobDao.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright 2006-2007 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.batch.execution.repository.dao; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.sql.Types; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.domain.BatchStatus; -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.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.RowMapper; -import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; -import org.springframework.util.Assert; - -/** - * Jdbc implementation of {@link JobDao}. Uses sequences (via Spring's - * {@link DataFieldMaxValueIncrementer} abstraction) to create all primary keys - * before inserting a new row. Objects are checked to ensure all mandatory - * fields to be stored are not null. If any are found to be null, an - * IllegalArgumentException will be thrown. This could be left to JdbcTemplate, - * however, the exception will be fairly vague, and fails to highlight which - * field caused the exception. - * - * @author Lucas Ward - * @author Dave Syer - */ -public class JdbcJobDao extends AbstractJdbcBatchMetadataDao implements JobDao, InitializingBean { - - 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(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY)" - + " values (?, ?, ?)"; - - 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 (?, ?, ?, ?, ?, ?)"; - - private static final int EXIT_MESSAGE_LENGTH = 250; - - 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(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(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 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 JOB_EXECUTION_ID = ?"; - - private DataFieldMaxValueIncrementer jobExecutionIncrementer; - - private DataFieldMaxValueIncrementer jobIncrementer; - - /* - * (non-Javadoc) - * - * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() - * - * Ensure jdbcTemplate and incrementers have been provided. - */ - public void afterPropertiesSet() throws Exception { - Assert.notNull(jobIncrementer, "JobIncrementor cannot be null"); - Assert.notNull(jobExecutionIncrementer, - "JobExecutionIncrementer cannot be null"); - } - - /** - * In this sql implementation a job id is obtained by asking the - * jobIncrementer (which is likely a sequence) for the nextLong, and then - * passing the Id and identifier values (job name, jobKey, schedule date) - * into an INSERT statement. - * - * @see JobDao#createJob(JobIdentifier) - * @throws IllegalArgumentException - * if any {@link JobIdentifier} fields are null. - */ - public JobInstance createJobInstance(String jobName, JobParameters jobParameters) { - - Assert.notNull(jobName, "Job Name must not be null."); - Assert.notNull(jobParameters, "JobParameters must not be null."); - - Long jobId = new Long(jobIncrementer.nextLongValue()); - Object[] parameters = new Object[] { jobId, jobName, createJobKey(jobParameters) }; - getJdbcTemplate().update(getCreateJobQuery(), parameters, new int[] { - Types.INTEGER, Types.VARCHAR, Types.VARCHAR}); - - insertJobParameters(jobId, jobParameters); - - JobInstance jobInstance = new JobInstance(jobId, jobParameters); - return jobInstance; - } - - private String createJobKey(JobParameters jobParameters){ - - Map props = jobParameters.getParameters(); - StringBuilder stringBuilder = new StringBuilder(); - for(Iterator it = props.entrySet().iterator();it.hasNext();){ - Entry entry = (Entry)it.next(); - stringBuilder.append(entry.toString() + ";"); - } - - return stringBuilder.toString(); - } - - public List findJobExecutions(final JobInstance job) { - - Assert.notNull(job, "Job cannot be null."); - Assert.notNull(job.getId(), "Job Id cannot be null."); - - return getJdbcTemplate().query( - 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 = getJdbcTemplate().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 - * given identifier, adding them to a list via the RowMapper callback. - * - * @see JobDao#findJobInstances(JobIdentifier) - * @throws IllegalArgumentException - * if any {@link JobIdentifier} fields are null. - */ - public List findJobInstances(final String jobName, final JobParameters jobParameters) { - - Assert.notNull(jobName, "Job Name must not be null."); - Assert.notNull(jobParameters, "JobParameters must not be null."); - - Object[] parameters = new Object[] { jobName, - createJobKey(jobParameters) }; - - RowMapper rowMapper = new RowMapper() { - public Object mapRow(ResultSet rs, int rowNum) throws SQLException { - - 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; - } - }; - - return getJdbcTemplate().query(getFindJobsQuery(), parameters, rowMapper); - } - - private String getCheckJobExecutionExistsQuery() { - return getQuery(CHECK_JOB_EXECUTION_EXISTS); - } - - private String getCreateJobQuery() { - return getQuery(CREATE_JOB); - } - - private String getFindJobsQuery() { - return getQuery(FIND_JOBS); - } - - private String getCreateJobParamsQuery(){ - return getQuery(CREATE_JOB_PARAMETERS); - } - - /** - * @see JobDao#getJobExecutionCount(JobInstance) - * @throws IllegalArgumentException - * if jobId is null. - */ - public int getJobExecutionCount(Long jobId) { - - Assert.notNull(jobId, "JobId cannot be null"); - - Object[] parameters = new Object[] { jobId }; - - return getJdbcTemplate() - .queryForInt(getJobExecutionCountQuery(), parameters); - } - - private String getJobExecutionCountQuery() { - return getQuery(GET_JOB_EXECUTION_COUNT); - } - - private String getSaveJobExecutionQuery() { - return getQuery(SAVE_JOB_EXECUTION); - } - - private String getUpdateJobExecutionQuery() { - return getQuery(UPDATE_JOB_EXECUTION); - } - - private String getUpdateJobQuery() { - return getQuery(UPDATE_JOB); - } - - /* - * Convenience method that inserts all parameters from the provided JobParameters. - * - */ - private void insertJobParameters(Long jobId, JobParameters jobParameters){ - - Map parameters = jobParameters.getStringParameters(); - - if(!parameters.isEmpty()){ - for(Iterator it = parameters.entrySet().iterator(); it.hasNext();){ - Entry entry = (Entry)it.next(); - insertParameter(jobId, ParameterType.STRING, entry.getKey().toString(), entry.getValue()); - } - } - - parameters = jobParameters.getLongParameters(); - - if(!parameters.isEmpty()){ - for(Iterator it = parameters.entrySet().iterator(); it.hasNext();){ - Entry entry = (Entry)it.next(); - insertParameter(jobId, ParameterType.LONG, entry.getKey().toString(), entry.getValue()); - } - } - - parameters = jobParameters.getDateParameters(); - - if(!parameters.isEmpty()){ - for(Iterator it = parameters.entrySet().iterator(); it.hasNext();){ - Entry entry = (Entry)it.next(); - insertParameter(jobId, ParameterType.DATE, entry.getKey().toString(), entry.getValue()); - } - } - } - - /* - * Convenience method that inserts an individual records into the JobParameters table. - */ - private void insertParameter(Long jobId, ParameterType type, String key, Object value){ - - Object[] args = new Object[0]; - int[] argTypes = new int[]{Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP, Types.INTEGER}; - - if(type == ParameterType.STRING){ - args = new Object[]{jobId, key, type, value, new Timestamp(0L), new Long(0)}; - } - else if(type == ParameterType.LONG){ - args = new Object[]{jobId, key, type, "", new Timestamp(0L), value}; - } - else if(type == ParameterType.DATE){ - args = new Object[]{jobId, key, type, "", value, new Long(0)}; - } - - getJdbcTemplate().update(getCreateJobParamsQuery(), args, argTypes); - } - - /** - * - * SQL implementation using Sequences via the Spring incrementer - * abstraction. Once a new id has been obtained, the JobExecution is saved - * via a SQL INSERT statement. - * - * @see JobDao#saveJobExecution(JobExecution) - * @throws IllegalArgumentException - * if jobExecution is null, as well as any of it's fields to be - * persisted. - */ - public void saveJobExecution(JobExecution jobExecution) { - - validateJobExecution(jobExecution); - - jobExecution.setId(new Long(jobExecutionIncrementer.nextLongValue())); - Object[] parameters = new Object[] { jobExecution.getId(), - jobExecution.getJobId(), jobExecution.getStartTime(), - jobExecution.getEndTime(), jobExecution.getStatus().toString(), - jobExecution.getExitStatus().isContinuable() ? "Y" : "N", - jobExecution.getExitStatus().getExitCode(), - jobExecution.getExitStatus().getExitDescription() }; - getJdbcTemplate().update(getSaveJobExecutionQuery(), parameters, new int[] { - Types.INTEGER, Types.INTEGER, Types.TIMESTAMP, Types.TIMESTAMP, - Types.VARCHAR, Types.CHAR, Types.VARCHAR, Types.VARCHAR }); - } - - /** - * Setter for {@link DataFieldMaxValueIncrementer} to be used when - * generating primary keys for {@link JobExecution} instances. - * - * @param jobExecutionIncrementer - * the {@link DataFieldMaxValueIncrementer} - */ - public void setJobExecutionIncrementer( - DataFieldMaxValueIncrementer jobExecutionIncrementer) { - this.jobExecutionIncrementer = jobExecutionIncrementer; - } - - /** - * Setter for {@link DataFieldMaxValueIncrementer} to be used when - * generating primary keys for {@link JobInstance} instances. - * - * @param jobIncrementer - * the {@link DataFieldMaxValueIncrementer} - */ - public void setJobIncrementer(DataFieldMaxValueIncrementer jobIncrementer) { - this.jobIncrementer = jobIncrementer; - } - - /** - * Update given JobExecution using a SQL UPDATE statement. The JobExecution - * is first checked to ensure all fields are not null, and that it has an - * ID. The database is then queried to ensure that the ID exists, which - * ensures that it is valid. - * - * @see JobDao#updateJobExecution(JobExecution) - */ - public void updateJobExecution(JobExecution jobExecution) { - - validateJobExecution(jobExecution); - - String exitDescription = jobExecution.getExitStatus() - .getExitDescription(); - if (exitDescription != null - && exitDescription.length() > EXIT_MESSAGE_LENGTH) { - exitDescription = exitDescription.substring(0, EXIT_MESSAGE_LENGTH); - logger - .debug("Truncating long message before update of JobExecution: " - + jobExecution); - } - Object[] parameters = new Object[] { jobExecution.getStartTime(), - jobExecution.getEndTime(), jobExecution.getStatus().toString(), - jobExecution.getExitStatus().isContinuable() ? "Y" : "N", - jobExecution.getExitStatus().getExitCode(), exitDescription, - jobExecution.getId() }; - - if (jobExecution.getId() == null) { - throw new IllegalArgumentException( - "JobExecution ID cannot be null. JobExecution must be saved " - + "before it can be updated."); - } - - // Check if given JobExecution's Id already exists, if none is found it - // is invalid and - // an exception should be thrown. - if (getJdbcTemplate().queryForInt(getCheckJobExecutionExistsQuery(), - new Object[] { jobExecution.getId() }) != 1) { - throw new NoSuchBatchDomainObjectException( - "Invalid JobExecution, ID " + jobExecution.getId() - + " not found."); - } - - getJdbcTemplate() - .update(getUpdateJobExecutionQuery(), parameters, - new int[] { Types.TIMESTAMP, Types.TIMESTAMP, - Types.VARCHAR, Types.CHAR, Types.VARCHAR, - Types.VARCHAR, Types.INTEGER }); - } - - /** - * @see JobDao#updateJobInstance(JobInstance) - * @throws IllegalArgumentException - * if Job, Job.status, or job.id is null - */ - public void updateJobInstance(JobInstance jobInstance) { - - 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() }; - getJdbcTemplate().update(getUpdateJobQuery(), parameters, new int[] { - Types.INTEGER, Types.INTEGER}); - } - - /* - * Validate JobExecution. At a minimum, JobId, StartTime, EndTime, and - * Status cannot be null. - * - * @param jobExecution @throws IllegalArgumentException - */ - private void validateJobExecution(JobExecution jobExecution) { - - Assert.notNull(jobExecution); - Assert.notNull(jobExecution.getJobId(), - "JobExecution Job-Id cannot be null."); - Assert.notNull(jobExecution.getStartTime(), - "JobExecution start time cannot be null."); - Assert.notNull(jobExecution.getStatus(), - "JobExecution status cannot be null."); - } - - /** - * Re-usable mapper for {@link JobExecution} instances. - * - * @author Dave Syer - * - */ - public static class JobExecutionRowMapper implements RowMapper { - - 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 JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%JOB_EXECUTION" - + " where JOB_EXECUTION_ID = ?"; - - private JobInstance job; - - public JobExecutionRowMapper(JobInstance job) { - super(); - this.job = job; - } - - public Object mapRow(ResultSet rs, int rowNum) throws SQLException { - JobExecution jobExecution = new JobExecution(job); - jobExecution.setId(new Long(rs.getLong(1))); - jobExecution.setStartTime(rs.getTimestamp(2)); - jobExecution.setEndTime(rs.getTimestamp(3)); - jobExecution.setStatus(BatchStatus.getStatus(rs.getString(4))); - jobExecution.setExitStatus(new ExitStatus("Y".equals(rs - .getString(5)), rs.getString(6), rs.getString(7))); - return jobExecution; - } - - } - - private static class ParameterType { - - private final String type; - - private ParameterType(String type) { - this.type = type; - } - - public String toString(){ - return type; - } - - public static final ParameterType STRING = new ParameterType("STRING"); - - public static final ParameterType DATE = new ParameterType("DATE"); - - public static final ParameterType LONG = new ParameterType("LONG"); - - private static final ParameterType[] VALUES = {STRING, DATE, LONG}; - - public static ParameterType getType(String typeAsString){ - - for(int i = 0; i < VALUES.length; i++){ - if(VALUES[i].toString().equals(typeAsString)){ - return (ParameterType)VALUES[i]; - } - } - - return null; - } - } -} diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobExecutionDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobExecutionDao.java new file mode 100644 index 000000000..506334658 --- /dev/null +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobExecutionDao.java @@ -0,0 +1,243 @@ +package org.springframework.batch.execution.repository.dao; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.batch.core.domain.BatchStatus; +import org.springframework.batch.core.domain.JobExecution; +import org.springframework.batch.core.domain.JobInstance; +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.RowMapper; +import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; +import org.springframework.util.Assert; + +/** + * Jdbc implementation of {@link JobExecutionDao}. Uses sequences (via Spring's + * {@link DataFieldMaxValueIncrementer} abstraction) to create all primary keys + * before inserting a new row. Objects are checked to ensure all mandatory + * fields to be stored are not null. If any are found to be null, an + * IllegalArgumentException will be thrown. This could be left to JdbcTemplate, + * however, the exception will be fairly vague, and fails to highlight which + * field caused the exception. + * + * @author Lucas Ward + * @author Dave Syer + * @author Robert Kasanicky + */ +public class JdbcJobExecutionDao extends AbstractJdbcBatchMetadataDao implements JobExecutionDao, InitializingBean { + + private static final Log logger = LogFactory.getLog(JdbcJobExecutionDao.class); + + private static final int EXIT_MESSAGE_LENGTH = 250; + + private static final String GET_JOB_EXECUTION_COUNT = "SELECT count(JOB_EXECUTION_ID) from %PREFIX%JOB_EXECUTION " + + "where JOB_INSTANCE_ID = ?"; + + 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 CHECK_JOB_EXECUTION_EXISTS = "SELECT COUNT(*) FROM %PREFIX%JOB_EXECUTION WHERE JOB_EXECUTION_ID = ?"; + + private static final String UPDATE_JOB_EXECUTION = "UPDATE %PREFIX%JOB_EXECUTION set START_TIME = ?, END_TIME = ?, " + + " STATUS = ?, CONTINUABLE = ?, EXIT_CODE = ?, EXIT_MESSAGE = ? where JOB_EXECUTION_ID = ?"; + + private DataFieldMaxValueIncrementer jobExecutionIncrementer; + + public List findJobExecutions(final JobInstance job) { + + Assert.notNull(job, "Job cannot be null."); + Assert.notNull(job.getId(), "Job Id cannot be null."); + + return getJdbcTemplate().query(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 = getJdbcTemplate().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; + } + + /** + * @see JobDao#getJobExecutionCount(JobInstance) + * @throws IllegalArgumentException + * if jobId is null. + */ + public int getJobExecutionCount(Long jobId) { + + Assert.notNull(jobId, "JobId cannot be null"); + + Object[] parameters = new Object[] { jobId }; + + return getJdbcTemplate() + .queryForInt(getQuery(GET_JOB_EXECUTION_COUNT), parameters); + } + + /** + * + * SQL implementation using Sequences via the Spring incrementer + * abstraction. Once a new id has been obtained, the JobExecution is saved + * via a SQL INSERT statement. + * + * @see JobDao#saveJobExecution(JobExecution) + * @throws IllegalArgumentException + * if jobExecution is null, as well as any of it's fields to be + * persisted. + */ + public void saveJobExecution(JobExecution jobExecution) { + + validateJobExecution(jobExecution); + + jobExecution.setId(new Long(jobExecutionIncrementer.nextLongValue())); + Object[] parameters = new Object[] { jobExecution.getId(), + jobExecution.getJobId(), jobExecution.getStartTime(), + jobExecution.getEndTime(), jobExecution.getStatus().toString(), + jobExecution.getExitStatus().isContinuable() ? "Y" : "N", + jobExecution.getExitStatus().getExitCode(), + jobExecution.getExitStatus().getExitDescription() }; + getJdbcTemplate().update(getQuery(SAVE_JOB_EXECUTION), parameters, new int[] { + Types.INTEGER, Types.INTEGER, Types.TIMESTAMP, Types.TIMESTAMP, + Types.VARCHAR, Types.CHAR, Types.VARCHAR, Types.VARCHAR }); + } + + /** + * Validate JobExecution. At a minimum, JobId, StartTime, EndTime, and + * Status cannot be null. + * + * @param jobExecution @throws IllegalArgumentException + */ + private void validateJobExecution(JobExecution jobExecution) { + + Assert.notNull(jobExecution); + Assert.notNull(jobExecution.getJobId(), + "JobExecution Job-Id cannot be null."); + Assert.notNull(jobExecution.getStartTime(), + "JobExecution start time cannot be null."); + Assert.notNull(jobExecution.getStatus(), + "JobExecution status cannot be null."); + } + + /** + * Update given JobExecution using a SQL UPDATE statement. The JobExecution + * is first checked to ensure all fields are not null, and that it has an + * ID. The database is then queried to ensure that the ID exists, which + * ensures that it is valid. + * + * @see JobDao#updateJobExecution(JobExecution) + */ + public void updateJobExecution(JobExecution jobExecution) { + + validateJobExecution(jobExecution); + + String exitDescription = jobExecution.getExitStatus() + .getExitDescription(); + if (exitDescription != null + && exitDescription.length() > EXIT_MESSAGE_LENGTH) { + exitDescription = exitDescription.substring(0, EXIT_MESSAGE_LENGTH); + logger + .debug("Truncating long message before update of JobExecution: " + + jobExecution); + } + Object[] parameters = new Object[] { jobExecution.getStartTime(), + jobExecution.getEndTime(), jobExecution.getStatus().toString(), + jobExecution.getExitStatus().isContinuable() ? "Y" : "N", + jobExecution.getExitStatus().getExitCode(), exitDescription, + jobExecution.getId() }; + + if (jobExecution.getId() == null) { + throw new IllegalArgumentException( + "JobExecution ID cannot be null. JobExecution must be saved " + + "before it can be updated."); + } + + // Check if given JobExecution's Id already exists, if none is found it + // is invalid and + // an exception should be thrown. + if (getJdbcTemplate().queryForInt(getQuery(CHECK_JOB_EXECUTION_EXISTS), + new Object[] { jobExecution.getId() }) != 1) { + throw new NoSuchBatchDomainObjectException( + "Invalid JobExecution, ID " + jobExecution.getId() + + " not found."); + } + + getJdbcTemplate() + .update(getQuery(UPDATE_JOB_EXECUTION), parameters, + new int[] { Types.TIMESTAMP, Types.TIMESTAMP, + Types.VARCHAR, Types.CHAR, Types.VARCHAR, + Types.VARCHAR, Types.INTEGER }); + } + + /** + * Setter for {@link DataFieldMaxValueIncrementer} to be used when + * generating primary keys for {@link JobExecution} instances. + * + * @param jobExecutionIncrementer + * the {@link DataFieldMaxValueIncrementer} + */ + public void setJobExecutionIncrementer( + DataFieldMaxValueIncrementer jobExecutionIncrementer) { + this.jobExecutionIncrementer = jobExecutionIncrementer; + } + + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + Assert.notNull(jobExecutionIncrementer); + } + + /** + * Re-usable mapper for {@link JobExecution} instances. + * + * @author Dave Syer + * + */ + public static class JobExecutionRowMapper implements RowMapper { + + 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 JOB_EXECUTION_ID, START_TIME, END_TIME, STATUS, CONTINUABLE, EXIT_CODE, EXIT_MESSAGE from %PREFIX%JOB_EXECUTION" + + " where JOB_EXECUTION_ID = ?"; + + private JobInstance job; + + public JobExecutionRowMapper(JobInstance job) { + super(); + this.job = job; + } + + public Object mapRow(ResultSet rs, int rowNum) throws SQLException { + JobExecution jobExecution = new JobExecution(job); + jobExecution.setId(new Long(rs.getLong(1))); + jobExecution.setStartTime(rs.getTimestamp(2)); + jobExecution.setEndTime(rs.getTimestamp(3)); + jobExecution.setStatus(BatchStatus.getStatus(rs.getString(4))); + jobExecution.setExitStatus(new ExitStatus("Y".equals(rs.getString(5)), rs.getString(6), rs.getString(7))); + return jobExecution; + } + + } + +} diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobInstanceDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobInstanceDao.java new file mode 100644 index 000000000..58ce99281 --- /dev/null +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcJobInstanceDao.java @@ -0,0 +1,245 @@ +package org.springframework.batch.execution.repository.dao; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.springframework.batch.core.domain.JobExecution; +import org.springframework.batch.core.domain.JobInstance; +import org.springframework.batch.core.domain.JobParameters; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; +import org.springframework.util.Assert; + +/** + * Jdbc implementation of {@link JobInstanceDao}. Uses sequences (via Spring's + * {@link DataFieldMaxValueIncrementer} abstraction) to create all primary keys + * before inserting a new row. Objects are checked to ensure all mandatory + * fields to be stored are not null. If any are found to be null, an + * IllegalArgumentException will be thrown. This could be left to JdbcTemplate, + * however, the exception will be fairly vague, and fails to highlight which + * field caused the exception. + * + * @author Lucas Ward + * @author Dave Syer + * @author Robert Kasanicky + */ +public class JdbcJobInstanceDao extends AbstractJdbcBatchMetadataDao implements JobInstanceDao, InitializingBean { + + 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_PARAMS(JOB_INSTANCE_ID, KEY_NAME, TYPE_CD, " + + "STRING_VAL, DATE_VAL, LONG_VAL) values (?, ?, ?, ?, ?, ?)"; + + 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 UPDATE_JOB = "UPDATE %PREFIX%JOB_INSTANCE set LAST_JOB_EXECUTION_ID = ? where JOB_INSTANCE_ID = ?"; + + private DataFieldMaxValueIncrementer jobIncrementer; + + private JobExecutionDao jobExecutionDao; + + /** + * In this jdbc implementation a job id is obtained by asking the + * jobIncrementer (which is likely a sequence) for the nextLong, and then + * passing the Id and parameter values into an INSERT statement. + * + * @see JobDao#createJob(JobIdentifier) + * @throws IllegalArgumentException if any {@link JobIdentifier} fields are + * null. + */ + public JobInstance createJobInstance(String jobName, JobParameters jobParameters) { + + Assert.notNull(jobName, "Job Name must not be null."); + Assert.notNull(jobParameters, "JobParameters must not be null."); + + Long jobId = new Long(jobIncrementer.nextLongValue()); + Object[] parameters = new Object[] { jobId, jobName, createJobKey(jobParameters) }; + getJdbcTemplate().update(getQuery(CREATE_JOB), parameters, + new int[] { Types.INTEGER, Types.VARCHAR, Types.VARCHAR }); + + insertJobParameters(jobId, jobParameters); + + JobInstance jobInstance = new JobInstance(jobId, jobParameters); + return jobInstance; + } + + private String createJobKey(JobParameters jobParameters) { + + Map props = jobParameters.getParameters(); + StringBuilder stringBuilder = new StringBuilder(); + for (Iterator it = props.entrySet().iterator(); it.hasNext();) { + Entry entry = (Entry) it.next(); + stringBuilder.append(entry.toString() + ";"); + } + + return stringBuilder.toString(); + } + + /** + * Convenience method that inserts all parameters from the provided + * JobParameters. + * + */ + private void insertJobParameters(Long jobId, JobParameters jobParameters) { + + Map parameters = jobParameters.getStringParameters(); + + if (!parameters.isEmpty()) { + for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) { + Entry entry = (Entry) it.next(); + insertParameter(jobId, ParameterType.STRING, entry.getKey().toString(), entry.getValue()); + } + } + + parameters = jobParameters.getLongParameters(); + + if (!parameters.isEmpty()) { + for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) { + Entry entry = (Entry) it.next(); + insertParameter(jobId, ParameterType.LONG, entry.getKey().toString(), entry.getValue()); + } + } + + parameters = jobParameters.getDateParameters(); + + if (!parameters.isEmpty()) { + for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) { + Entry entry = (Entry) it.next(); + insertParameter(jobId, ParameterType.DATE, entry.getKey().toString(), entry.getValue()); + } + } + } + + /** + * Convenience method that inserts an individual records into the + * JobParameters table. + */ + private void insertParameter(Long jobId, ParameterType type, String key, Object value) { + + Object[] args = new Object[0]; + int[] argTypes = new int[] { Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP, + Types.INTEGER }; + + if (type == ParameterType.STRING) { + args = new Object[] { jobId, key, type, value, new Timestamp(0L), new Long(0) }; + } + else if (type == ParameterType.LONG) { + args = new Object[] { jobId, key, type, "", new Timestamp(0L), value }; + } + else if (type == ParameterType.DATE) { + args = new Object[] { jobId, key, type, "", value, new Long(0) }; + } + + getJdbcTemplate().update(getQuery(CREATE_JOB_PARAMETERS), args, argTypes); + } + + /** + * The job table is queried for any jobs that match the + * given identifier, adding them to a list via the RowMapper callback. + * + * @see JobDao#findJobInstances(JobIdentifier) + * @throws IllegalArgumentException + * if any {@link JobIdentifier} fields are null. + */ + public List findJobInstances(final String jobName, final JobParameters jobParameters) { + + Assert.notNull(jobName, "Job Name must not be null."); + Assert.notNull(jobParameters, "JobParameters must not be null."); + + Object[] parameters = new Object[] { jobName, + createJobKey(jobParameters) }; + + RowMapper rowMapper = new RowMapper() { + public Object mapRow(ResultSet rs, int rowNum) throws SQLException { + + JobInstance jobInstance = new JobInstance(new Long(rs.getLong(1)), jobParameters); + long lastExecutionId = rs.getLong(2); + JobExecution lastExecution = jobExecutionDao.getJobExecution(new Long(lastExecutionId)); + if(lastExecution != null){ + lastExecution.setJobInstance(jobInstance); + } + jobInstance.setLastExecution(lastExecution); + return jobInstance; + } + }; + + return getJdbcTemplate().query(getQuery(FIND_JOBS), parameters, rowMapper); + } + + /** + * @see JobDao#updateJobInstance(JobInstance) + * @throws IllegalArgumentException + * if Job, Job.status, or job.id is null + */ + public void updateJobInstance(JobInstance jobInstance) { + + 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() }; + getJdbcTemplate().update(getQuery(UPDATE_JOB), parameters, new int[] { + Types.INTEGER, Types.INTEGER}); + } + + /** + * Setter for {@link DataFieldMaxValueIncrementer} to be used when + * generating primary keys for {@link JobInstance} instances. + * + * @param jobIncrementer the {@link DataFieldMaxValueIncrementer} + */ + public void setJobIncrementer(DataFieldMaxValueIncrementer jobIncrementer) { + this.jobIncrementer = jobIncrementer; + } + + public void setJobExecutionDao(JobExecutionDao jobExecutionDao) { + this.jobExecutionDao = jobExecutionDao; + } + + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + Assert.notNull(jobExecutionDao); + Assert.notNull(jobIncrementer); + } + + + private static class ParameterType { + + private final String type; + + private ParameterType(String type) { + this.type = type; + } + + public String toString() { + return type; + } + + public static final ParameterType STRING = new ParameterType("STRING"); + + public static final ParameterType DATE = new ParameterType("DATE"); + + public static final ParameterType LONG = new ParameterType("LONG"); + + private static final ParameterType[] VALUES = { STRING, DATE, LONG }; + + public static ParameterType getType(String typeAsString) { + + for (int i = 0; i < VALUES.length; i++) { + if (VALUES[i].toString().equals(typeAsString)) { + return (ParameterType) VALUES[i]; + } + } + + return null; + } + } +} diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepExecutionDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepExecutionDao.java index 9fdf84999..1f3890665 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepExecutionDao.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepExecutionDao.java @@ -16,7 +16,7 @@ import org.springframework.batch.core.domain.BatchStatus; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.execution.repository.dao.JdbcJobDao.JobExecutionRowMapper; +import org.springframework.batch.execution.repository.dao.JdbcJobExecutionDao.JobExecutionRowMapper; import org.springframework.batch.io.exception.BatchCriticalException; import org.springframework.batch.item.ExecutionAttributes; import org.springframework.batch.repeat.ExitStatus; @@ -91,7 +91,7 @@ public class JdbcStepExecutionDao extends AbstractJdbcBatchMetadataDao private DataFieldMaxValueIncrementer stepExecutionIncrementer; - private JobDao jobDao; + private JobExecutionDao jobExecutionDao; public ExecutionAttributes findExecutionAttributes(final Long executionId) { @@ -282,7 +282,7 @@ public class JdbcStepExecutionDao extends AbstractJdbcBatchMetadataDao // assume already saved... return; } - jobDao.saveJobExecution(jobExecution); + jobExecutionDao.saveJobExecution(jobExecution); } /** @@ -458,13 +458,13 @@ public class JdbcStepExecutionDao extends AbstractJdbcBatchMetadataDao this.stepExecutionIncrementer = stepExecutionIncrementer; } - public void setJobDao(JobDao jobDao) { - this.jobDao = jobDao; + public void setJobExecutionDao(JobExecutionDao jobExecutionDao) { + this.jobExecutionDao = jobExecutionDao; } public void afterPropertiesSet() throws Exception { Assert.notNull(stepExecutionIncrementer, "StepExecutionIncrementer cannot be null."); - Assert.notNull(jobDao, "JobDao cannot be null"); + Assert.notNull(jobExecutionDao, "JobDao cannot be null"); } public static class AttributeType { 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 721058eee..622b537a1 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 @@ -16,12 +16,6 @@ package org.springframework.batch.execution.repository.dao; -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. @@ -29,84 +23,6 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException; * @author Lucas Ward * */ -public interface JobDao { +public interface JobDao extends JobInstanceDao, JobExecutionDao { - /** - * Create a JobInstance with given name and parameters. - * - * PostConditions: A valid job will be returned which has been persisted and - * contains an unique Id. - * - * @param jobName - * @param jobParameters - * @return JobInstance - */ - JobInstance createJobInstance(String jobName, JobParameters jobParameters); - - /** - * Find all job instances that match the given name and parameters. If no - * matching job instances are found, then a list of size 0 will be - * returned. - * - * @param jobName - * @param jobParameters - * @return List of {@link JobInstance} objects matching - * {@link JobIdentifier} - */ - List findJobInstances(String jobName, JobParameters jobParameters); - - /** - * Update an existing JobInstance. - * - * Preconditions: jobInstance must have an ID. - * - * @param jobInstance - */ - void updateJobInstance(JobInstance jobInstance); - - /** - * Save a new JobExecution. - * - * Preconditions: jobExecution must have a jobInstanceId. - * - * @param jobExecution - */ - void saveJobExecution(JobExecution jobExecution); - - /** - * Update and existing JobExecution. - * - * Preconditions: jobExecution must have an Id (which can be obtained by the - * save method) and a jobInstanceId. - * - * @param jobExecution - */ - void updateJobExecution(JobExecution jobExecution); - - /** - * Return the number of JobExecutions with the given jobInstanceId - * - * Preconditions: jobInstance must have an id. - * - * @param jobInstanceId - */ - int getJobExecutionCount(Long jobInstanceId); - - /** - * Return list of JobExecutions for given JobInstance. - * - * @param jobInstance - * @return list of jobExecutions. - */ - 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. - */ - JobExecution getJobExecution(Long jobExecutionId); } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobExecutionDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobExecutionDao.java new file mode 100644 index 000000000..1de857560 --- /dev/null +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobExecutionDao.java @@ -0,0 +1,61 @@ +package org.springframework.batch.execution.repository.dao; + +import java.util.List; + +import org.springframework.batch.core.domain.JobExecution; +import org.springframework.batch.core.domain.JobInstance; + +/** + * Data Access Object for job executions. + * + * @author Lucas Ward + * @author Robert Kasanicky + */ +public interface JobExecutionDao { + + /** + * Save a new JobExecution. + * + * Preconditions: jobExecution must have a jobInstanceId. + * + * @param jobExecution + */ + void saveJobExecution(JobExecution jobExecution); + + /** + * Update and existing JobExecution. + * + * Preconditions: jobExecution must have an Id (which can be obtained by the + * save method) and a jobInstanceId. + * + * @param jobExecution + */ + void updateJobExecution(JobExecution jobExecution); + + /** + * Return the number of JobExecutions with the given jobInstanceId + * + * Preconditions: jobInstance must have an id. + * + * @param jobInstanceId + */ + int getJobExecutionCount(Long jobInstanceId); + + /** + * Return list of JobExecutions for given JobInstance. + * + * @param jobInstance + * @return list of jobExecutions. + */ + 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. + */ + JobExecution getJobExecution(Long jobExecutionId); +} diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobInstanceDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobInstanceDao.java new file mode 100644 index 000000000..5e5ef7bbb --- /dev/null +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JobInstanceDao.java @@ -0,0 +1,49 @@ +package org.springframework.batch.execution.repository.dao; + +import java.util.List; + +import org.springframework.batch.core.domain.JobInstance; +import org.springframework.batch.core.domain.JobParameters; + +/** + * Data Access Object for job instances. + * + * @author Lucas Ward + * @author Robert Kasanicky + * + */ +public interface JobInstanceDao { + + /** + * Create a JobInstance with given name and parameters. + * + * PostConditions: A valid job will be returned which has been persisted and + * contains an unique Id. + * + * @param jobName + * @param jobParameters + * @return JobInstance + */ + JobInstance createJobInstance(String jobName, JobParameters jobParameters); + + /** + * Find all job instances that match the given name and parameters. If no + * matching job instances are found, then a list of size 0 will be + * returned. + * + * @param jobName + * @param jobParameters + * @return List of {@link JobInstance} objects matching + * {@link JobIdentifier} + */ + List findJobInstances(String jobName, JobParameters jobParameters); + + /** + * Update an existing JobInstance. + * + * Preconditions: jobInstance must have an ID. + * + * @param jobInstance + */ + void updateJobInstance(JobInstance jobInstance); +} 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 e7e7aeffa..b2eaf4517 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 @@ -31,7 +31,8 @@ import org.springframework.batch.core.domain.StepInstance; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; import org.springframework.batch.execution.repository.SimpleJobRepository; -import org.springframework.batch.execution.repository.dao.JobDao; +import org.springframework.batch.execution.repository.dao.JobExecutionDao; +import org.springframework.batch.execution.repository.dao.JobInstanceDao; import org.springframework.batch.execution.repository.dao.MapJobDao; import org.springframework.batch.execution.repository.dao.MapStepDao; import org.springframework.batch.execution.repository.dao.StepExecutionDao; @@ -51,7 +52,9 @@ public class SimpleJobTests extends TestCase { private JobRepository jobRepository; - private JobDao jobDao; + private JobInstanceDao jobInstanceDao; + + private JobExecutionDao jobExecutionDao; private StepInstanceDao stepInstanceDao; @@ -84,10 +87,11 @@ public class SimpleJobTests extends TestCase { MapJobDao.clear(); MapStepDao.clear(); - jobDao = new MapJobDao(); + jobInstanceDao = new MapJobDao(); + jobExecutionDao = new MapJobDao(); stepInstanceDao = new MapStepDao(); stepExecutionDao = new MapStepDao(); - jobRepository = new SimpleJobRepository(jobDao, stepInstanceDao, stepExecutionDao); + jobRepository = new SimpleJobRepository(jobInstanceDao, jobExecutionDao, stepInstanceDao, stepExecutionDao); job = new SimpleJob(); job.setJobRepository(jobRepository); @@ -254,9 +258,9 @@ public class SimpleJobTests extends TestCase { * Check JobRepository to ensure status is being saved. */ private void checkRepository(BatchStatus status, ExitStatus exitStatus) { - assertEquals(jobInstance, jobDao.findJobInstances(jobInstance.getJobName(), jobParameters).get(0)); + assertEquals(jobInstance, jobInstanceDao.findJobInstances(jobInstance.getJobName(), jobParameters).get(0)); // because map dao stores in memory, it can be checked directly - JobExecution jobExecution = (JobExecution) jobDao.findJobExecutions(jobInstance).get(0); + JobExecution jobExecution = (JobExecution) jobExecutionDao.findJobExecutions(jobInstance).get(0); assertEquals(jobInstance.getId(), jobExecution.getJobId()); assertEquals(status, jobExecution.getStatus()); if (exitStatus != null) { 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 112f64cbe..2a927723f 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 @@ -49,7 +49,7 @@ public class SimpleJobTests extends TestCase { private List recovered = new ArrayList(); - private SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapStepDao(), new MapStepDao()); + private SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapJobDao(), new MapStepDao(), new MapStepDao()); private List processed = new ArrayList(); 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 5f7c2d631..a5cee4b56 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 @@ -86,7 +86,7 @@ public class SimpleJobRepositoryTests extends TestCase { jobDao = (JobDao) jobDaoControl.getMock(); stepDao = (StepDao) stepDaoControl.getMock(); - jobRepository = new SimpleJobRepository(jobDao, stepDao, stepDao); + jobRepository = new SimpleJobRepository(jobDao, jobDao, stepDao, stepDao); jobParameters = new JobParametersBuilder().toJobParameters(); 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 37e35a477..e6cfb4d2f 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 @@ -39,7 +39,9 @@ import org.springframework.util.ClassUtils; public abstract class AbstractJobDaoTests extends AbstractTransactionalDataSourceSpringContextTests { - protected JobDao jobDao; + protected JobInstanceDao jobInstanceDao; + + protected JobExecutionDao jobExecutionDao; protected JobParameters jobParameters = new JobParametersBuilder().addString("job.key", "jobKey").toJobParameters(); @@ -61,8 +63,12 @@ public abstract class AbstractJobDaoTests extends * Because AbstractTransactionalSpringContextTests is used, this method will * be called by Spring to set the JobRepository. */ - public void setJobRepositoryDao(JobDao jobRepositoryDao) { - this.jobDao = jobRepositoryDao; + public void setJobInstanceDao(JobInstanceDao jobInstanceDao) { + this.jobInstanceDao = jobInstanceDao; + } + + public void setJobExecutionDao(JobExecutionDao jobExecutionDao) { + this.jobExecutionDao = jobExecutionDao; } protected void onSetUpInTransaction() throws Exception { @@ -72,16 +78,16 @@ public abstract class AbstractJobDaoTests extends job = new JobSupport("Job1"); // Create job. - jobInstance = jobDao.createJobInstance(job.getName(), jobParameters); + jobInstance = jobInstanceDao.createJobInstance(job.getName(), jobParameters); // Create an execution jobExecutionStartTime = new Date(System.currentTimeMillis()); jobExecution = new JobExecution(jobInstance); jobExecution.setStartTime(jobExecutionStartTime); jobExecution.setStatus(BatchStatus.STARTED); - jobDao.saveJobExecution(jobExecution); + jobExecutionDao.saveJobExecution(jobExecution); jobInstance.setLastExecution(jobExecution); - jobDao.updateJobInstance(jobInstance); + jobInstanceDao.updateJobInstance(jobInstance); } public void testVersionIsNotNullForJob() throws Exception { @@ -100,13 +106,13 @@ public abstract class AbstractJobDaoTests extends public void testFindNonExistentJob() { // No job should be found since it hasn't been created. - List jobs = jobDao.findJobInstances("nonexistentJob", jobParameters); + List jobs = jobInstanceDao.findJobInstances("nonexistentJob", jobParameters); assertTrue(jobs.size() == 0); } public void testFindJob() { - List jobs = jobDao.findJobInstances(job.getName(), jobParameters); + List jobs = jobInstanceDao.findJobInstances(job.getName(), jobParameters); assertTrue(jobs.size() == 1); JobInstance tempJob = (JobInstance) jobs.get(0); assertTrue(jobInstance.equals(tempJob)); @@ -116,7 +122,7 @@ public abstract class AbstractJobDaoTests extends public void testFindJobWithNullRuntime() { try { - jobDao.findJobInstances(null, null); + jobInstanceDao.findJobInstances(null, null); fail(); } catch (IllegalArgumentException ex) { // expected @@ -130,7 +136,7 @@ public abstract class AbstractJobDaoTests extends */ public void testCreateJobWithExistingName() { - jobDao.createJobInstance("ScheduledJob", jobParameters); + jobInstanceDao.createJobInstance("ScheduledJob", jobParameters); // Modifying the key should bring back a completely different // JobInstance @@ -138,12 +144,12 @@ public abstract class AbstractJobDaoTests extends .toJobParameters(); List jobs; - jobs = jobDao.findJobInstances("ScheduledJob", jobParameters); + jobs = jobInstanceDao.findJobInstances("ScheduledJob", jobParameters); assertEquals(1, jobs.size()); JobInstance jobInstance = (JobInstance) jobs.get(0); assertEquals(jobParameters, jobInstance.getJobParameters()); - jobs = jobDao.findJobInstances("ScheduledJob", tempProps); + jobs = jobInstanceDao.findJobInstances("ScheduledJob", tempProps); assertEquals(0, jobs.size()); } @@ -151,12 +157,12 @@ public abstract class AbstractJobDaoTests extends public void testUpdateJob() { // Update the returned job with a new status JobExecution newExecution = new JobExecution(jobInstance); - jobDao.saveJobExecution(newExecution); + jobExecutionDao.saveJobExecution(newExecution); jobInstance.setLastExecution(newExecution); - jobDao.updateJobInstance(jobInstance); + jobInstanceDao.updateJobInstance(jobInstance); // The job just updated should be found, with the saved status. - List jobs = jobDao.findJobInstances(job.getName(), jobParameters); + List jobs = jobInstanceDao.findJobInstances(job.getName(), jobParameters); assertTrue(jobs.size() == 1); JobInstance tempJob = (JobInstance) jobs.get(0); assertTrue(jobInstance.equals(tempJob)); @@ -165,13 +171,13 @@ public abstract class AbstractJobDaoTests extends public void testGetJobExecution(){ - JobExecution tempExecution = jobDao.getJobExecution(jobExecution.getId()); + JobExecution tempExecution = jobExecutionDao.getJobExecution(jobExecution.getId()); assertEquals(jobExecution, tempExecution); } public void testJobInstanceLastExecution(){ //ensure the last execution id is being stored - JobExecution lastJobExecution = jobDao.getJobExecution(jobInstance.getLastExecution().getId()); + JobExecution lastJobExecution = jobExecutionDao.getJobExecution(jobInstance.getLastExecution().getId()); assertEquals(lastJobExecution, jobExecution); } @@ -180,7 +186,7 @@ public abstract class AbstractJobDaoTests extends try { JobInstance testJob = new JobInstance(null, null); - jobDao.updateJobInstance(testJob); + jobInstanceDao.updateJobInstance(testJob); fail(); } catch (IllegalArgumentException ex) { // expected @@ -191,7 +197,7 @@ public abstract class AbstractJobDaoTests extends JobInstance testJob = null; try { - jobDao.updateJobInstance(testJob); + jobInstanceDao.updateJobInstance(testJob); } catch (IllegalArgumentException ex) { // expected } @@ -202,9 +208,9 @@ public abstract class AbstractJobDaoTests extends jobExecution.setStatus(BatchStatus.COMPLETED); jobExecution.setExitStatus(ExitStatus.FINISHED); jobExecution.setEndTime(new Date(System.currentTimeMillis())); - jobDao.updateJobExecution(jobExecution); + jobExecutionDao.updateJobExecution(jobExecution); - List executions = jobDao.findJobExecutions(jobInstance); + List executions = jobExecutionDao.findJobExecutions(jobInstance); assertEquals(executions.size(), 1); validateJobExecution(jobExecution, (JobExecution) executions.get(0)); @@ -212,7 +218,7 @@ public abstract class AbstractJobDaoTests extends public void testSaveJobExecution(){ - List executions = jobDao.findJobExecutions(jobInstance); + List executions = jobExecutionDao.findJobExecutions(jobInstance); assertEquals(executions.size(), 1); validateJobExecution(jobExecution, (JobExecution) executions.get(0)); } @@ -222,7 +228,7 @@ public abstract class AbstractJobDaoTests extends // id is invalid JobExecution execution = new JobExecution(jobInstance, new Long(29432)); try { - jobDao.updateJobExecution(execution); + jobExecutionDao.updateJobExecution(execution); fail("Expected NoSuchBatchDomainObjectException"); } catch (NoSuchBatchDomainObjectException ex) { // expected @@ -233,7 +239,7 @@ public abstract class AbstractJobDaoTests extends JobExecution execution = new JobExecution(jobInstance); try { - jobDao.updateJobExecution(execution); + jobExecutionDao.updateJobExecution(execution); fail(); } catch (IllegalArgumentException ex) { // expected @@ -243,26 +249,26 @@ public abstract class AbstractJobDaoTests extends public void testIncrementExecutionCount() { // 1 JobExection already added in setup - assertEquals(jobDao.getJobExecutionCount(jobInstance.getId()), 1); + assertEquals(jobExecutionDao.getJobExecutionCount(jobInstance.getId()), 1); // Save new JobExecution for same job JobExecution testJobExecution = new JobExecution(jobInstance); - jobDao.saveJobExecution(testJobExecution); + jobExecutionDao.saveJobExecution(testJobExecution); // JobExecutionCount should be incremented by 1 - assertEquals(jobDao.getJobExecutionCount(jobInstance.getId()), 2); + assertEquals(jobExecutionDao.getJobExecutionCount(jobInstance.getId()), 2); } public void testZeroExecutionCount() { - JobInstance testJob = jobDao.createJobInstance("test", new JobParameters()); + JobInstance testJob = jobInstanceDao.createJobInstance("test", new JobParameters()); // no jobExecutions saved for new job, count should be 0 - assertEquals(jobDao.getJobExecutionCount(testJob.getId()), 0); + assertEquals(jobExecutionDao.getJobExecutionCount(testJob.getId()), 0); } public void testJobWithSimpleJobIdentifier() throws Exception { // Create job. - jobInstance = jobDao.createJobInstance("test", jobParameters); + jobInstance = jobInstanceDao.createJobInstance("test", jobParameters); List jobs = jdbcTemplate.queryForList( "SELECT * FROM BATCH_JOB_INSTANCE where JOB_INSTANCE_ID=?", new Object[] { jobInstance @@ -274,9 +280,9 @@ public abstract class AbstractJobDaoTests extends public void testJobWithDefaultJobIdentifier() throws Exception { // Create job. - jobInstance = jobDao.createJobInstance("testDefault", jobParameters); + jobInstance = jobInstanceDao.createJobInstance("testDefault", jobParameters); - List jobs = jobDao.findJobInstances("testDefault", jobParameters); + List jobs = jobInstanceDao.findJobInstances("testDefault", jobParameters); assertEquals(1, jobs.size()); assertEquals(jobParameters.getString("job.key"), ((JobInstance) jobs.get(0)) @@ -286,7 +292,7 @@ public abstract class AbstractJobDaoTests extends public void testFindJobExecutions(){ - List results = jobDao.findJobExecutions(jobInstance); + List results = jobExecutionDao.findJobExecutions(jobInstance); assertEquals(results.size(), 1); validateJobExecution(jobExecution, (JobExecution)results.get(0)); } 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 057b08e5e..cfa43d98e 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 @@ -44,7 +44,7 @@ import org.springframework.util.ClassUtils; */ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSourceSpringContextTests { - protected JobDao jobDao; + protected JobInstanceDao jobInstanceDao; protected StepInstanceDao stepInstanceDao; @@ -64,8 +64,8 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour protected ExecutionAttributes executionAttributes; - public void setJobDao(JobDao jobDao) { - this.jobDao = jobDao; + public void setJobInstanceDao(JobInstanceDao jobInstanceDao) { + this.jobInstanceDao = jobInstanceDao; } public void setStepInstanceDao(StepInstanceDao stepInstanceDao) { @@ -90,7 +90,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour */ protected void onSetUpInTransaction() throws Exception { Job job = new JobSupport("TestJob"); - jobInstance = jobDao.createJobInstance(job.getName(), jobParameters); + jobInstance = jobInstanceDao.createJobInstance(job.getName(), jobParameters); step1 = stepInstanceDao.createStepInstance(jobInstance, "TestStep1"); step2 = stepInstanceDao.createStepInstance(jobInstance, "TestStep2"); jobExecution = new JobExecution(step2.getJobInstance()); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcJobDaoQueryTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcJobDaoQueryTests.java index 40e79f84f..ba935d32b 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcJobDaoQueryTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcJobDaoQueryTests.java @@ -31,8 +31,8 @@ import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer * */ public class JdbcJobDaoQueryTests extends TestCase { - - JdbcJobDao sqlDao; + + JdbcJobExecutionDao jobExecutionDao; List list = new ArrayList(); @@ -41,8 +41,9 @@ public class JdbcJobDaoQueryTests extends TestCase { * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { - sqlDao = new JdbcJobDao(); - sqlDao.setJobExecutionIncrementer(new DataFieldMaxValueIncrementer() { + + jobExecutionDao = new JdbcJobExecutionDao(); + jobExecutionDao.setJobExecutionIncrementer(new DataFieldMaxValueIncrementer() { public int nextIntValue() throws DataAccessException { return 0; @@ -60,14 +61,14 @@ public class JdbcJobDaoQueryTests extends TestCase { } public void testTablePrefix() throws Exception { - sqlDao.setTablePrefix("FOO_"); - sqlDao.setJdbcTemplate(new JdbcTemplate() { + jobExecutionDao.setTablePrefix("FOO_"); + jobExecutionDao.setJdbcTemplate(new JdbcTemplate() { public int update(String sql, Object[] args, int[] argTypes) throws DataAccessException { list.add(sql); return 1; } }); - sqlDao.saveJobExecution(new JobInstance(new Long(11), new JobParameters()).createJobExecution()); + jobExecutionDao.saveJobExecution(new JobInstance(new Long(11), new JobParameters()).createJobExecution()); assertEquals(1, list.size()); String query = (String) list.get(0); assertTrue("Query did not contain FOO_:" + query, query.indexOf("FOO_") >= 0); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcJobDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcJobDaoTests.java index cbee1d4e6..6befe0b54 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcJobDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcJobDaoTests.java @@ -10,7 +10,8 @@ public class JdbcJobDaoTests extends AbstractJobDaoTests { public static final String LONG_STRING = "A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String A very long String "; protected void onSetUpBeforeTransaction() throws Exception { - ((JdbcJobDao) jobDao).setTablePrefix(JdbcJobDao.DEFAULT_TABLE_PREFIX); + ((JdbcJobInstanceDao) jobInstanceDao).setTablePrefix(AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX); + ((JdbcJobExecutionDao) jobExecutionDao).setTablePrefix(AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX); } public void testUpdateJobExecutionWithLongExitCode() { @@ -18,7 +19,7 @@ public class JdbcJobDaoTests extends AbstractJobDaoTests { assertTrue(LONG_STRING.length() > 250); jobExecution.setExitStatus(ExitStatus.FINISHED .addExitDescription(LONG_STRING)); - jobDao.updateJobExecution(jobExecution); + jobExecutionDao.updateJobExecution(jobExecution); List executions = jdbcTemplate.queryForList( "SELECT * FROM BATCH_JOB_EXECUTION where JOB_INSTANCE_ID=?", 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 245181dde..83b8a33bc 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 @@ -46,7 +46,7 @@ public class JdbcStepDaoPrefixTests extends TestCase { stepInstanceDao = new JdbcStepInstanceDao(); stepExecutionDao = new JdbcStepExecutionDao(); - stepExecutionDao.setJobDao(new MapJobDao()); + stepExecutionDao.setJobExecutionDao(new MapJobDao()); stepExecutionIncrementer = (DataFieldMaxValueIncrementer)stepExecutionIncrementerControl.getMock(); stepIncrementer = (DataFieldMaxValueIncrementer)stepIncrementerControl.getMock(); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcStepDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcStepDaoTests.java index 65bfb1010..c93705f06 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcStepDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/JdbcStepDaoTests.java @@ -11,8 +11,8 @@ public class JdbcStepDaoTests extends AbstractStepDaoTests { private static final String LONG_STRING = JdbcJobDaoTests.LONG_STRING; protected void onSetUpBeforeTransaction() throws Exception { - ((JdbcStepInstanceDao) stepInstanceDao).setTablePrefix(JdbcJobDao.DEFAULT_TABLE_PREFIX); - ((JdbcStepExecutionDao) stepExecutionDao).setTablePrefix(JdbcJobDao.DEFAULT_TABLE_PREFIX); + ((JdbcStepInstanceDao) stepInstanceDao).setTablePrefix(AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX); + ((JdbcStepExecutionDao) stepExecutionDao).setTablePrefix(AbstractJdbcBatchMetadataDao.DEFAULT_TABLE_PREFIX); } public void testTablePrefix() throws Exception { 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 dd8eab773..bcdef0e75 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 @@ -202,7 +202,7 @@ public class SimpleStepExecutorTests extends TestCase { public void testRepository() throws Exception { - SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapStepDao(), new MapStepDao()); + SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapJobDao(), new MapStepDao(), new MapStepDao()); stepExecutor.setRepository(repository); StepInstance step = new StepInstance(new Long(1)); 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 78e87a351..f3001dd2c 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 @@ -55,7 +55,7 @@ public class StepExecutorInterruptionTests extends TestCase { public void setUp() throws Exception { - jobRepository = new SimpleJobRepository(jobDao, stepDao, stepDao); + jobRepository = new SimpleJobRepository(jobDao, jobDao, stepDao, stepDao); JobSupport jobConfiguration = new JobSupport(); step = new RepeatOperationsStep(); diff --git a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/repository/dao/sql-dao-test.xml b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/repository/dao/sql-dao-test.xml index 62906a0a2..2ac4dd0b2 100644 --- a/spring-batch-execution/src/test/resources/org/springframework/batch/execution/repository/dao/sql-dao-test.xml +++ b/spring-batch-execution/src/test/resources/org/springframework/batch/execution/repository/dao/sql-dao-test.xml @@ -5,10 +5,15 @@ - + - - + + + + + + + @@ -20,7 +25,7 @@ - + diff --git a/spring-batch-execution/src/test/resources/simple-container-definition.xml b/spring-batch-execution/src/test/resources/simple-container-definition.xml index fe2937f94..4ad2ab088 100644 --- a/spring-batch-execution/src/test/resources/simple-container-definition.xml +++ b/spring-batch-execution/src/test/resources/simple-container-definition.xml @@ -45,6 +45,7 @@ + diff --git a/spring-batch-samples/src/main/resources/simple-container-definition.xml b/spring-batch-samples/src/main/resources/simple-container-definition.xml index bcdc933b4..062004d2c 100644 --- a/spring-batch-samples/src/main/resources/simple-container-definition.xml +++ b/spring-batch-samples/src/main/resources/simple-container-definition.xml @@ -45,17 +45,23 @@ - + + - + - - + + + + + + + - +