IN PROGRESS - issue BATCH-340: Refactor JobRepository for greater clarity and consistency.

http://jira.springframework.org/browse/BATCH-340

StepDao split into StepInstanceDao and StepExecutionDao. AbstractJdbcBatchMetadataDao created to remove the duplications.
This commit is contained in:
robokaso
2008-02-11 16:15:24 +00:00
parent 7b26bc4f2e
commit 0824f1aeb3
19 changed files with 1020 additions and 986 deletions

View File

@@ -32,7 +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.StepDao;
import org.springframework.batch.execution.repository.dao.StepExecutionDao;
import org.springframework.batch.execution.repository.dao.StepInstanceDao;
import org.springframework.batch.item.ExecutionAttributes;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.util.Assert;
@@ -56,7 +57,9 @@ public class SimpleJobRepository implements JobRepository {
private JobDao jobDao;
private StepDao stepDao;
private StepInstanceDao stepInstanceDao;
private StepExecutionDao stepExecutionDao;
/**
* Provide default constructor with low visibility in case user wants to use
@@ -65,10 +68,11 @@ public class SimpleJobRepository implements JobRepository {
SimpleJobRepository() {
}
public SimpleJobRepository(JobDao jobDao, StepDao stepDao) {
public SimpleJobRepository(JobDao jobDao, StepInstanceDao stepInstanceDao, StepExecutionDao stepExecutionDao) {
super();
this.jobDao = jobDao;
this.stepDao = stepDao;
this.stepInstanceDao = stepInstanceDao;
this.stepExecutionDao = stepExecutionDao;
}
/**
@@ -85,8 +89,8 @@ public class SimpleJobRepository implements JobRepository {
* There are two ways in which the method determines if a job should be
* created or an existing one should be returned. The first is
* restartability. The {@link JobSupport} restartable property will be
* checked first. If it is false, a new job will be created, regardless
* of whether or not one exists. If it is true, the {@link JobDao} will be
* checked first. If it is false, a new job will be created, regardless of
* whether or not one exists. If it is true, the {@link JobDao} will be
* checked to determine if the job already exists, if it does, it's steps
* will be populated (there must be at least 1) and a new
* {@link JobExecution} will be returned. If no job is found, a new one will
@@ -256,13 +260,13 @@ public class SimpleJobRepository implements JobRepository {
if (stepExecution.getId() == null) {
// new execution, obtain id and insert
stepDao.saveStepExecution(stepExecution);
stepDao.saveExecutionAttributes(stepExecution.getId(), stepExecution.getExecutionAttributes());
stepExecutionDao.saveStepExecution(stepExecution);
stepExecutionDao.saveExecutionAttributes(stepExecution.getId(), stepExecution.getExecutionAttributes());
}
else {
// existing execution, update
stepDao.updateStepExecution(stepExecution);
stepDao.updateExecutionAttributes(stepExecution.getId(), stepExecution.getExecutionAttributes());
stepExecutionDao.updateStepExecution(stepExecution);
stepExecutionDao.updateExecutionAttributes(stepExecution.getId(), stepExecution.getExecutionAttributes());
}
}
@@ -278,7 +282,7 @@ public class SimpleJobRepository implements JobRepository {
Assert.notNull(step.getId(), "Step cannot be updated if it's ID is null. It must be obtained"
+ "from SimpleJobRepository.findOrCreateJob to be considered valid.");
stepDao.updateStepInstance(step);
stepInstanceDao.updateStepInstance(step);
}
@@ -304,7 +308,7 @@ public class SimpleJobRepository implements JobRepository {
Iterator i = steps.iterator();
while (i.hasNext()) {
Step step = (Step) i.next();
StepInstance stepInstance = stepDao.createStepInstance(job, step.getName());
StepInstance stepInstance = stepInstanceDao.createStepInstance(job, step.getName());
stepInstances.add(stepInstance);
}
@@ -320,15 +324,15 @@ public class SimpleJobRepository implements JobRepository {
while (i.hasNext()) {
Step stepConfiguration = (Step) i.next();
StepInstance stepInstance = stepDao.findStepInstance(jobInstance, stepConfiguration.getName());
StepInstance stepInstance = stepInstanceDao.findStepInstance(jobInstance, stepConfiguration.getName());
if (stepInstance != null) {
if (stepInstance.getLastExecution() != null) {
ExecutionAttributes executionAttributes = stepDao.findExecutionAttributes(stepInstance
ExecutionAttributes executionAttributes = stepExecutionDao.findExecutionAttributes(stepInstance
.getLastExecution().getId());
stepInstance.getLastExecution().setExecutionAttributes(executionAttributes);
}
stepInstance.setStepExecutionCount(stepDao.getStepExecutionCount(stepInstance));
stepInstance.setStepExecutionCount(stepExecutionDao.getStepExecutionCount(stepInstance));
stepInstances.add(stepInstance);
}
}

View File

@@ -0,0 +1,56 @@
package org.springframework.batch.execution.repository.dao;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Encapsulates common functionality needed by JDBC batch metadata DAOs -
* provides jdbcTemplate for subclasses and handles table prefixes.
*
* @author Robert Kasanicky
*/
public abstract class AbstractJdbcBatchMetadataDao implements InitializingBean {
/**
* Default value for the table prefix property.
*/
public static final String DEFAULT_TABLE_PREFIX = "BATCH_";
private String tablePrefix = DEFAULT_TABLE_PREFIX;
private JdbcOperations jdbcTemplate;
protected String getQuery(String base) {
return StringUtils.replace(base, "%PREFIX%", tablePrefix);
}
/**
* Public setter for the table prefix property. This will be prefixed to all
* the table names before queries are executed. Defaults to
* {@value #DEFAULT_TABLE_PREFIX}.
*
* @param tablePrefix the tablePrefix to set
*/
public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix;
}
public void setJdbcTemplate(JdbcOperations jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
protected String getTablePrefix() {
return tablePrefix;
}
protected JdbcOperations getJdbcTemplate() {
return jdbcTemplate;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(jdbcTemplate);
}
}

View File

@@ -35,11 +35,9 @@ import org.springframework.batch.core.repository.NoSuchBatchDomainObjectExceptio
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;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Jdbc implementation of {@link JobDao}. Uses sequences (via Spring's
@@ -53,7 +51,7 @@ import org.springframework.util.StringUtils;
* @author Lucas Ward
* @author Dave Syer
*/
public class JdbcJobDao implements JobDao, InitializingBean {
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 = ?";
@@ -63,11 +61,6 @@ public class JdbcJobDao implements JobDao, InitializingBean {
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 (?, ?, ?, ?, ?, ?)";
/**
* Default value for the table prefix property.
*/
public static final String DEFAULT_TABLE_PREFIX = "BATCH_";
private static final int EXIT_MESSAGE_LENGTH = 250;
@@ -87,14 +80,10 @@ public class JdbcJobDao implements JobDao, InitializingBean {
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 JdbcOperations jdbcTemplate;
private DataFieldMaxValueIncrementer jobExecutionIncrementer;
private DataFieldMaxValueIncrementer jobIncrementer;
private String tablePrefix = DEFAULT_TABLE_PREFIX;
/*
* (non-Javadoc)
*
@@ -103,8 +92,6 @@ public class JdbcJobDao implements JobDao, InitializingBean {
* Ensure jdbcTemplate and incrementers have been provided.
*/
public void afterPropertiesSet() throws Exception {
Assert.notNull(jdbcTemplate, "JdbcTemplate cannot be null");
Assert.notNull(jobIncrementer, "JobIncrementor cannot be null");
Assert.notNull(jobExecutionIncrementer,
"JobExecutionIncrementer cannot be null");
@@ -127,7 +114,7 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Long jobId = new Long(jobIncrementer.nextLongValue());
Object[] parameters = new Object[] { jobId, jobName, createJobKey(jobParameters) };
jdbcTemplate.update(getCreateJobQuery(), parameters, new int[] {
getJdbcTemplate().update(getCreateJobQuery(), parameters, new int[] {
Types.INTEGER, Types.VARCHAR, Types.VARCHAR});
insertJobParameters(jobId, jobParameters);
@@ -153,7 +140,7 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Assert.notNull(job, "Job cannot be null.");
Assert.notNull(job.getId(), "Job Id cannot be null.");
return jdbcTemplate.query(
return getJdbcTemplate().query(
getQuery(JobExecutionRowMapper.FIND_JOB_EXECUTIONS),
new Object[] { job.getId() }, new JobExecutionRowMapper(job));
}
@@ -162,7 +149,7 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Assert.notNull(jobExecutionId, "Job Execution id must not be null.");
List executions = jdbcTemplate.query(
List executions = getJdbcTemplate().query(
getQuery(JobExecutionRowMapper.GET_JOB_EXECUTION),
new Object[] { jobExecutionId }, new JobExecutionRowMapper(null));
@@ -211,7 +198,7 @@ public class JdbcJobDao implements JobDao, InitializingBean {
}
};
return jdbcTemplate.query(getFindJobsQuery(), parameters, rowMapper);
return getJdbcTemplate().query(getFindJobsQuery(), parameters, rowMapper);
}
private String getCheckJobExecutionExistsQuery() {
@@ -241,7 +228,7 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Object[] parameters = new Object[] { jobId };
return jdbcTemplate
return getJdbcTemplate()
.queryForInt(getJobExecutionCountQuery(), parameters);
}
@@ -249,10 +236,6 @@ public class JdbcJobDao implements JobDao, InitializingBean {
return getQuery(GET_JOB_EXECUTION_COUNT);
}
private String getQuery(String base) {
return StringUtils.replace(base, "%PREFIX%", tablePrefix);
}
private String getSaveJobExecutionQuery() {
return getQuery(SAVE_JOB_EXECUTION);
}
@@ -317,7 +300,7 @@ public class JdbcJobDao implements JobDao, InitializingBean {
args = new Object[]{jobId, key, type, "", value, new Long(0)};
}
jdbcTemplate.update(getCreateJobParamsQuery(), args, argTypes);
getJdbcTemplate().update(getCreateJobParamsQuery(), args, argTypes);
}
/**
@@ -342,15 +325,11 @@ public class JdbcJobDao implements JobDao, InitializingBean {
jobExecution.getExitStatus().isContinuable() ? "Y" : "N",
jobExecution.getExitStatus().getExitCode(),
jobExecution.getExitStatus().getExitDescription() };
jdbcTemplate.update(getSaveJobExecutionQuery(), parameters, new int[] {
getJdbcTemplate().update(getSaveJobExecutionQuery(), parameters, new int[] {
Types.INTEGER, Types.INTEGER, Types.TIMESTAMP, Types.TIMESTAMP,
Types.VARCHAR, Types.CHAR, Types.VARCHAR, Types.VARCHAR });
}
public void setJdbcTemplate(JdbcOperations jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
/**
* Setter for {@link DataFieldMaxValueIncrementer} to be used when
* generating primary keys for {@link JobExecution} instances.
@@ -374,18 +353,6 @@ public class JdbcJobDao implements JobDao, InitializingBean {
this.jobIncrementer = jobIncrementer;
}
/**
* Public setter for the table prefix property. This will be prefixed to all
* the table names before queries are executed. Defaults to
* {@value #DEFAULT_TABLE_PREFIX}.
*
* @param tablePrefix
* the tablePrefix to set
*/
public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix;
}
/**
* 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
@@ -422,14 +389,14 @@ public class JdbcJobDao implements JobDao, InitializingBean {
// Check if given JobExecution's Id already exists, if none is found it
// is invalid and
// an exception should be thrown.
if (jdbcTemplate.queryForInt(getCheckJobExecutionExistsQuery(),
if (getJdbcTemplate().queryForInt(getCheckJobExecutionExistsQuery(),
new Object[] { jobExecution.getId() }) != 1) {
throw new NoSuchBatchDomainObjectException(
"Invalid JobExecution, ID " + jobExecution.getId()
+ " not found.");
}
jdbcTemplate
getJdbcTemplate()
.update(getUpdateJobExecutionQuery(), parameters,
new int[] { Types.TIMESTAMP, Types.TIMESTAMP,
Types.VARCHAR, Types.CHAR, Types.VARCHAR,
@@ -448,7 +415,7 @@ public class JdbcJobDao implements JobDao, InitializingBean {
Long lastExecutionId = jobInstance.getLastExecution() == null ? null : jobInstance.getLastExecution().getId();
Object[] parameters = new Object[] { lastExecutionId, jobInstance.getId() };
jdbcTemplate.update(getUpdateJobQuery(), parameters, new int[] {
getJdbcTemplate().update(getUpdateJobQuery(), parameters, new int[] {
Types.INTEGER, Types.INTEGER});
}

View File

@@ -0,0 +1,183 @@
package org.springframework.batch.execution.repository.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
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 StepInstanceDao}.<br/>
*
* Allows customization of the tables names used by Spring Batch for step meta
* data via a prefix property.<br/>
*
* Uses sequences or tables (via Spring's {@link DataFieldMaxValueIncrementer}
* abstraction) to create all primary keys before inserting a new row. All
* objects are checked to ensure all 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.<br/>
*
* @author Lucas Ward
* @author Dave Syer
* @author Robert Kasanicky
*
* @see StepInstanceDao
*/
public class JdbcStepInstanceDao extends AbstractJdbcBatchMetadataDao implements StepInstanceDao, InitializingBean {
private static final String CREATE_STEP = "INSERT into %PREFIX%STEP_INSTANCE(STEP_INSTANCE_ID, JOB_INSTANCE_ID, STEP_NAME) values (?, ?, ?)";
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_STEPS = "SELECT STEP_INSTANCE_ID, LAST_STEP_EXECUTION_ID, STEP_NAME from %PREFIX%STEP_INSTANCE where JOB_INSTANCE_ID = ?";
private static final String UPDATE_STEP = "UPDATE %PREFIX%STEP_INSTANCE set LAST_STEP_EXECUTION_ID = ? where STEP_INSTANCE_ID = ?";
private DataFieldMaxValueIncrementer stepIncrementer;
private StepExecutionDao stepExecutionDao;
/**
* Create a step with the given job's id, and the provided step name. A
* unique id is created for the step using an incrementer. (@link
* DataFieldMaxValueIncrementer)
*
* @see StepDao#createStepInstance(JobInstance, String)
* @throws IllegalArgumentException if job or stepName is null.
*/
public StepInstance createStepInstance(JobInstance job, String stepName) {
Assert.notNull(job, "Job cannot be null.");
Assert.notNull(stepName, "StepName cannot be null.");
Long stepId = new Long(stepIncrementer.nextLongValue());
Object[] parameters = new Object[] { stepId, job.getId(), stepName };
getJdbcTemplate().update(getQuery(CREATE_STEP), parameters);
StepInstance step = new StepInstance(job, stepName, stepId);
return step;
}
/**
* Find one step for given job and stepName. A RowMapper is used to map each
* row returned to a step object. If none are found, the list will be empty
* and null will be returned. If one step is found, it will be returned. If
* anymore than one step is found, an exception is thrown.
*
* @see StepDao#findStepInstance(Long, String)
* @throws IllegalArgumentException if job, stepName, or job.id is null.
* @throws IncorrectResultSizeDataAccessException if more than one step is
* found.
*/
public StepInstance findStepInstance(JobInstance jobInstance, String stepName) {
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[] { jobInstance.getId(), stepName };
RowMapper rowMapper = new StepInstanceRowMapper(jobInstance, stepName);
List steps = getJdbcTemplate().query(getQuery(FIND_STEP), parameters, rowMapper);
if (steps.size() == 0) {
// No step found
return null;
}
else if (steps.size() == 1) {
StepInstance step = (StepInstance) steps.get(0);
return step;
}
else {
// This error will likely never be thrown, because there should
// 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:" + jobInstance.getId(), 1, steps.size());
}
}
/**
* @see StepDao#findStepInstances(JobInstance)
*
* Sql implementation which uses a RowMapper to populate a list of all rows
* in the step table with the same JOB_INSTANCE_ID.
*
* @throws IllegalArgumentException if jobId is null.
*/
public List findStepInstances(final JobInstance jobInstance) {
Assert.notNull(jobInstance, "Job cannot be null.");
Object[] parameters = new Object[] { jobInstance.getId() };
RowMapper rowMapper = new StepInstanceRowMapper(jobInstance, null);
return getJdbcTemplate().query(getQuery(FIND_STEPS), parameters, rowMapper);
}
/**
* @see StepDao#updateStepInstance(StepInstance)
* @throws IllegalArgumentException if step, or it's status and id is null.
*/
public void updateStepInstance(final StepInstance step) {
Assert.notNull(step, "Step cannot be null.");
Assert.notNull(step.getId(), "Step Id cannot be null.");
Object[] parameters = new Object[] { step.getLastExecution().getId(), step.getId() };
getJdbcTemplate().update(getQuery(UPDATE_STEP), parameters);
}
public void setStepIncrementer(DataFieldMaxValueIncrementer stepIncrementer) {
this.stepIncrementer = stepIncrementer;
}
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 = stepExecutionDao.getStepExecution(new Long(rs.getLong(2)), stepInstance);
stepInstance.setLastExecution(lastExecution);
return stepInstance;
}
}
public void setStepExecutionDao(StepExecutionDao stepExecutionDao) {
this.stepExecutionDao = stepExecutionDao;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(stepIncrementer, "StepIncrementer cannot be null.");
Assert.notNull(stepExecutionDao, "StepExecutionDao cannot be null.");
}
}

View File

@@ -16,13 +16,6 @@
package org.springframework.batch.execution.repository.dao;
import java.util.List;
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.
@@ -30,117 +23,6 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException;
* @author Lucas Ward
*
*/
public interface StepDao {
public interface StepDao extends StepInstanceDao, StepExecutionDao{
/**
* Find a step with the given JobId and Step Name. Return null if none are
* found.
*
* @param jobInstance
* @param stepName
* @return StepInstance
*/
StepInstance findStepInstance(JobInstance jobInstance, String stepName);
/**
* Find all StepInstances of the given JobInstance.
*
* @param jobInstance the job to use as a search key
* @return list of {@link StepInstance}
*/
List findStepInstances(JobInstance jobInstance);
/**
* Create a StepInstance for the given name and JobInstance.
*
* @param jobInstance
* @param stepName
*
* @return
*/
StepInstance createStepInstance(JobInstance jobInstance, String stepName);
/**
* Update an existing StepInstance.
*
* Preconditions: StepInstance must have an ID.
*
* @param job
*/
void updateStepInstance(StepInstance stepInstance);
/**
* Save the given StepExecution.
*
* Preconditions: Id must be null.
*
* Postconditions: Id will be set to a unique Long.
*
* @param stepExecution
*/
void saveStepExecution(StepExecution stepExecution);
/**
* Update the given StepExecution
*
* Preconditions: Id must not be null.
*
* @param stepExecution
*/
void updateStepExecution(StepExecution stepExecution);
/**
* Return the count of StepExecutions for the given {@link StepInstance}.
*
* @param stepInstance the {@link StepInstance} to check for executions
* @return the number of step executions for this step
*/
int getStepExecutionCount(StepInstance stepInstance);
/**
* Return all StepExecutions for the given step.
*
* @param stepInstance the step to use as a search key
* @return list of stepExecutions
*/
List findStepExecutions(StepInstance stepInstance);
/**
* 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.
*/
StepExecution getStepExecution(Long stepExecutionId, StepInstance stepInstance);
/**
* Find all {@link ExecutionAttributes} for the given execution id.
*
* @param executionId - Long id of the {@link StepExecution} that the
* attributes belongs to.
* @return attributes for the provided id. If none are found, an empty
* {@link ExecutionAttributes} will be returned.
* @throws IllegalArgumentException if the id is null.
*/
ExecutionAttributes findExecutionAttributes(final Long executionId);
/**
* Save the provided {@link ExecutionAttributes} for the given executionId.
*
* @param executionId to be saved
* @param executionAttributes to be saved.
* @throws IllegalArgumentException if the executionId or attributes are
* null.
*/
void saveExecutionAttributes(final Long executionId, final ExecutionAttributes executionAttributes);
/**
* Update the provided ExecutionAttributes.
*
* @param executionId
* @param executionAttributes
*/
void updateExecutionAttributes(final Long executionId, ExecutionAttributes executionAttributes);
}

View File

@@ -0,0 +1,86 @@
package org.springframework.batch.execution.repository.dao;
import java.util.List;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInstance;
import org.springframework.batch.item.ExecutionAttributes;
public interface StepExecutionDao {
/**
* Save the given StepExecution.
*
* Preconditions: Id must be null.
*
* Postconditions: Id will be set to a unique Long.
*
* @param stepExecution
*/
void saveStepExecution(StepExecution stepExecution);
/**
* Update the given StepExecution
*
* Preconditions: Id must not be null.
*
* @param stepExecution
*/
void updateStepExecution(StepExecution stepExecution);
/**
* Return the count of StepExecutions for the given {@link StepInstance}.
*
* @param stepInstance the {@link StepInstance} to check for executions
* @return the number of step executions for this step
*/
int getStepExecutionCount(StepInstance stepInstance);
/**
* Return all StepExecutions for the given step.
*
* @param stepInstance the step to use as a search key
* @return list of stepExecutions
*/
List findStepExecutions(StepInstance stepInstance);
/**
* 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.
*/
StepExecution getStepExecution(Long stepExecutionId, StepInstance stepInstance);
/**
* Find all {@link ExecutionAttributes} for the given execution id.
*
* @param executionId - Long id of the {@link StepExecution} that the
* attributes belongs to.
* @return attributes for the provided id. If none are found, an empty
* {@link ExecutionAttributes} will be returned.
* @throws IllegalArgumentException if the id is null.
*/
ExecutionAttributes findExecutionAttributes(final Long executionId);
/**
* Save the provided {@link ExecutionAttributes} for the given executionId.
*
* @param executionId to be saved
* @param executionAttributes to be saved.
* @throws IllegalArgumentException if the executionId or attributes are
* null.
*/
void saveExecutionAttributes(final Long executionId, final ExecutionAttributes executionAttributes);
/**
* Update the provided ExecutionAttributes.
*
* @param executionId
* @param executionAttributes
*/
void updateExecutionAttributes(final Long executionId, ExecutionAttributes executionAttributes);
}

View File

@@ -0,0 +1,46 @@
package org.springframework.batch.execution.repository.dao;
import java.util.List;
import org.springframework.batch.core.domain.JobInstance;
import org.springframework.batch.core.domain.StepInstance;
public interface StepInstanceDao {
/**
* Find a step with the given JobId and Step Name. Return null if none are
* found.
*
* @param jobInstance
* @param stepName
* @return StepInstance
*/
StepInstance findStepInstance(JobInstance jobInstance, String stepName);
/**
* Find all StepInstances of the given JobInstance.
*
* @param jobInstance the job to use as a search key
* @return list of {@link StepInstance}
*/
List findStepInstances(JobInstance jobInstance);
/**
* Create a StepInstance for the given name and JobInstance.
*
* @param jobInstance
* @param stepName
*
* @return
*/
StepInstance createStepInstance(JobInstance jobInstance, String stepName);
/**
* Update an existing StepInstance.
*
* Preconditions: StepInstance must have an ID.
*
* @param job
*/
void updateStepInstance(StepInstance stepInstance);
}

View File

@@ -34,7 +34,8 @@ import org.springframework.batch.execution.repository.SimpleJobRepository;
import org.springframework.batch.execution.repository.dao.JobDao;
import org.springframework.batch.execution.repository.dao.MapJobDao;
import org.springframework.batch.execution.repository.dao.MapStepDao;
import org.springframework.batch.execution.repository.dao.StepDao;
import org.springframework.batch.execution.repository.dao.StepExecutionDao;
import org.springframework.batch.execution.repository.dao.StepInstanceDao;
import org.springframework.batch.execution.step.simple.SimpleStep;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.item.reader.AbstractItemReader;
@@ -52,7 +53,9 @@ public class SimpleJobTests extends TestCase {
private JobDao jobDao;
private StepDao stepDao;
private StepInstanceDao stepInstanceDao;
private StepExecutionDao stepExecutionDao;
private List list = new ArrayList();
@@ -82,8 +85,9 @@ public class SimpleJobTests extends TestCase {
MapJobDao.clear();
MapStepDao.clear();
jobDao = new MapJobDao();
stepDao = new MapStepDao();
jobRepository = new SimpleJobRepository(jobDao, stepDao);
stepInstanceDao = new MapStepDao();
stepExecutionDao = new MapStepDao();
jobRepository = new SimpleJobRepository(jobDao, stepInstanceDao, stepExecutionDao);
job = new SimpleJob();
job.setJobRepository(jobRepository);

View File

@@ -49,7 +49,7 @@ public class SimpleJobTests extends TestCase {
private List recovered = new ArrayList();
private SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapStepDao());
private SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapStepDao(), new MapStepDao());
private List processed = new ArrayList();

View File

@@ -86,7 +86,7 @@ public class SimpleJobRepositoryTests extends TestCase {
jobDao = (JobDao) jobDaoControl.getMock();
stepDao = (StepDao) stepDaoControl.getMock();
jobRepository = new SimpleJobRepository(jobDao, stepDao);
jobRepository = new SimpleJobRepository(jobDao, stepDao, stepDao);
jobParameters = new JobParametersBuilder().toJobParameters();

View File

@@ -35,7 +35,7 @@ import org.springframework.test.AbstractTransactionalDataSourceSpringContextTest
import org.springframework.util.ClassUtils;
/**
* Test for StepDao. Because it is very reasonable to assume that there is a
* Tests for step persistence (StepInstanceDao and StepExecutionDao). Because it is very reasonable to assume that there is a
* foreign key constraint on the JobId of a step, the JobDao is used to create
* jobs, to have an id for creating steps.
*
@@ -45,8 +45,10 @@ import org.springframework.util.ClassUtils;
public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSourceSpringContextTests {
protected JobDao jobDao;
protected StepDao stepDao;
protected StepInstanceDao stepInstanceDao;
protected StepExecutionDao stepExecutionDao;
protected JobInstance jobInstance;
@@ -66,8 +68,12 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
this.jobDao = jobDao;
}
public void setStepDao(StepDao stepDao) {
this.stepDao = stepDao;
public void setStepInstanceDao(StepInstanceDao stepInstanceDao) {
this.stepInstanceDao = stepInstanceDao;
}
public void setStepExecutionDao(StepExecutionDao stepExecutionDao) {
this.stepExecutionDao = stepExecutionDao;
}
/*
@@ -85,16 +91,16 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
protected void onSetUpInTransaction() throws Exception {
Job job = new JobSupport("TestJob");
jobInstance = jobDao.createJobInstance(job.getName(), jobParameters);
step1 = stepDao.createStepInstance(jobInstance, "TestStep1");
step2 = stepDao.createStepInstance(jobInstance, "TestStep2");
step1 = stepInstanceDao.createStepInstance(jobInstance, "TestStep1");
step2 = stepInstanceDao.createStepInstance(jobInstance, "TestStep2");
jobExecution = new JobExecution(step2.getJobInstance());
stepExecution = new StepExecution(step1, jobExecution, null);
stepExecution.setStatus(BatchStatus.STARTED);
stepExecution.setStartTime(new Date(System.currentTimeMillis()));
stepDao.saveStepExecution(stepExecution);
stepExecutionDao.saveStepExecution(stepExecution);
step1.setLastExecution(stepExecution);
stepDao.updateStepInstance(step1);
stepInstanceDao.updateStepInstance(step1);
executionAttributes = new ExecutionAttributes();
executionAttributes.putString("1", "testString1");
@@ -118,19 +124,19 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testFindStepNull() {
StepInstance step = stepDao.findStepInstance(jobInstance, "UnSavedStep");
StepInstance step = stepInstanceDao.findStepInstance(jobInstance, "UnSavedStep");
assertNull(step);
}
public void testFindStep() {
StepInstance tempStep = stepDao.findStepInstance(jobInstance, "TestStep1");
StepInstance tempStep = stepInstanceDao.findStepInstance(jobInstance, "TestStep1");
assertEquals(tempStep, step1);
}
public void testFindSteps() {
List steps = stepDao.findStepInstances(jobInstance);
List steps = stepInstanceDao.findStepInstances(jobInstance);
assertEquals(steps.size(), 2);
assertTrue(steps.contains(step1));
assertTrue(steps.contains(step2));
@@ -139,29 +145,29 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testFindStepsNotSaved() {
// no steps are saved for given id, empty list should be returned
List steps = stepDao.findStepInstances(new JobInstance(new Long(38922), jobParameters));
List steps = stepInstanceDao.findStepInstances(new JobInstance(new Long(38922), jobParameters));
assertEquals(steps.size(), 0);
}
public void testCreateStep() {
StepInstance step3 = stepDao.createStepInstance(jobInstance, "TestStep3");
StepInstance tempStep = stepDao.findStepInstance(jobInstance, "TestStep3");
StepInstance step3 = stepInstanceDao.createStepInstance(jobInstance, "TestStep3");
StepInstance tempStep = stepInstanceDao.findStepInstance(jobInstance, "TestStep3");
assertEquals(step3, tempStep);
}
public void testUpdateStepWithoutExecutionAttributes() {
stepDao.updateStepInstance(step1);
StepInstance tempStep = stepDao.findStepInstance(jobInstance, step1.getName());
stepInstanceDao.updateStepInstance(step1);
StepInstance tempStep = stepInstanceDao.findStepInstance(jobInstance, step1.getName());
assertEquals(tempStep, step1);
}
public void testUpdateStepWithExecutionAttributes() {
stepDao.saveExecutionAttributes(step1.getId(), executionAttributes);
StepInstance tempStep = stepDao.findStepInstance(jobInstance, step1.getName());
ExecutionAttributes tempAttributes = stepDao.findExecutionAttributes(step1.getId());
stepExecutionDao.saveExecutionAttributes(step1.getId(), executionAttributes);
StepInstance tempStep = stepInstanceDao.findStepInstance(jobInstance, step1.getName());
ExecutionAttributes tempAttributes = stepExecutionDao.findExecutionAttributes(step1.getId());
assertEquals(tempStep, step1);
assertEquals(executionAttributes, tempAttributes);
}
@@ -174,8 +180,8 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
execution.setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties("key1=0,key2=5")));
execution.setExitStatus(new ExitStatus(false, ExitCodeExceptionClassifier.FATAL_EXCEPTION,
"java.lang.Exception"));
stepDao.saveStepExecution(execution);
List executions = stepDao.findStepExecutions(step2);
stepExecutionDao.saveStepExecution(execution);
List executions = stepExecutionDao.findStepExecutions(step2);
assertEquals(1, executions.size());
StepExecution tempExecution = (StepExecution) executions.get(0);
assertEquals(execution, tempExecution);
@@ -192,8 +198,8 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
stepExecution.setExecutionAttributes(new ExecutionAttributes());
stepExecution.setExitStatus(new ExitStatus(false, ExitCodeExceptionClassifier.FATAL_EXCEPTION,
"java.lang.Exception"));
stepDao.updateStepExecution(stepExecution);
List executions = stepDao.findStepExecutions(step1);
stepExecutionDao.updateStepExecution(stepExecution);
List executions = stepExecutionDao.findStepExecutions(step1);
assertEquals(1, executions.size());
StepExecution tempExecution = (StepExecution) executions.get(0);
assertEquals(stepExecution, tempExecution);
@@ -203,7 +209,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testUpdateStepExecutionWithNullId() {
StepExecution stepExecution = new StepExecution(null, null, null);
try {
stepDao.updateStepExecution(stepExecution);
stepExecutionDao.updateStepExecution(stepExecution);
fail("Expected IllegalArgumentException");
}
catch (IllegalArgumentException ex) {
@@ -213,22 +219,22 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testGetStepExecutionCountForNoExecutions() {
int executionCount = stepDao.getStepExecutionCount(step2);
int executionCount = stepExecutionDao.getStepExecutionCount(step2);
assertEquals(executionCount, 0);
}
public void testIncrementStepExecutionCount() {
assertEquals(1, stepDao.getStepExecutionCount(step1));
assertEquals(1, stepExecutionDao.getStepExecutionCount(step1));
StepExecution execution = new StepExecution(step1, new JobExecution(step1.getJobInstance(), new Long(123)),
null);
stepDao.saveStepExecution(execution);
assertEquals(2, stepDao.getStepExecutionCount(step1));
stepExecutionDao.saveStepExecution(execution);
assertEquals(2, stepExecutionDao.getStepExecutionCount(step1));
}
public void testUpdateStepExecutionVersion() throws Exception {
int before = stepExecution.getVersion().intValue();
stepDao.updateStepExecution(stepExecution);
stepExecutionDao.updateStepExecution(stepExecution);
int after = stepExecution.getVersion().intValue();
assertEquals("StepExecution version not updated", before + 1, after);
}
@@ -237,7 +243,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
stepExecution.incrementVersion(); // not really allowed outside dao
// code
try {
stepDao.updateStepExecution(stepExecution);
stepExecutionDao.updateStepExecution(stepExecution);
fail("Expected OptimisticLockingFailureException");
}
catch (OptimisticLockingFailureException e) {
@@ -251,12 +257,12 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour
public void testSaveExecutionAttributes(){
stepDao.saveExecutionAttributes(stepExecution.getId(), executionAttributes);
ExecutionAttributes attributes = stepDao.findExecutionAttributes(stepExecution.getId());
stepExecutionDao.saveExecutionAttributes(stepExecution.getId(), executionAttributes);
ExecutionAttributes attributes = stepExecutionDao.findExecutionAttributes(stepExecution.getId());
assertEquals(executionAttributes, attributes);
executionAttributes.putString("newString", "newString");
stepDao.updateExecutionAttributes(stepExecution.getId(), executionAttributes);
attributes = stepDao.findExecutionAttributes(stepExecution.getId());
stepExecutionDao.updateExecutionAttributes(stepExecution.getId(), executionAttributes);
attributes = stepExecutionDao.findExecutionAttributes(stepExecution.getId());
assertEquals(executionAttributes, attributes);
}

View File

@@ -26,7 +26,9 @@ import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer
*/
public class JdbcStepDaoPrefixTests extends TestCase {
private JdbcStepDao stepDao;
private JdbcStepInstanceDao stepInstanceDao;
private JdbcStepExecutionDao stepExecutionDao;
MockJdbcTemplate jdbcTemplate = new MockJdbcTemplate();
@@ -42,14 +44,16 @@ public class JdbcStepDaoPrefixTests extends TestCase {
protected void setUp() throws Exception {
super.setUp();
stepDao = new JdbcStepDao();
stepDao.setJobDao(new MapJobDao());
stepInstanceDao = new JdbcStepInstanceDao();
stepExecutionDao = new JdbcStepExecutionDao();
stepExecutionDao.setJobDao(new MapJobDao());
stepExecutionIncrementer = (DataFieldMaxValueIncrementer)stepExecutionIncrementerControl.getMock();
stepIncrementer = (DataFieldMaxValueIncrementer)stepIncrementerControl.getMock();
stepDao.setJdbcTemplate(jdbcTemplate);
stepDao.setStepExecutionIncrementer(stepExecutionIncrementer);
stepDao.setStepIncrementer(stepIncrementer);
stepInstanceDao.setJdbcTemplate(jdbcTemplate);
stepExecutionDao.setJdbcTemplate(jdbcTemplate);
stepExecutionDao.setStepExecutionIncrementer(stepExecutionIncrementer);
stepInstanceDao.setStepIncrementer(stepIncrementer);
stepExecution.setId(new Long(1));
stepExecution.incrementVersion();
step.setLastExecution(stepExecution);
@@ -59,51 +63,51 @@ public class JdbcStepDaoPrefixTests extends TestCase {
}
public void testModifiedUpdateStepExecution(){
stepDao.setTablePrefix("FOO_");
stepDao.updateStepExecution(stepExecution);
stepExecutionDao.setTablePrefix("FOO_");
stepExecutionDao.updateStepExecution(stepExecution);
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP_EXECUTION") != -1);
}
public void testModifiedSaveStepExecution(){
stepDao.setTablePrefix("FOO_");
stepExecutionDao.setTablePrefix("FOO_");
stepExecutionIncrementer.nextLongValue();
stepExecutionIncrementerControl.setReturnValue(1);
stepExecutionIncrementerControl.replay();
stepDao.saveStepExecution(stepExecution);
stepExecutionDao.saveStepExecution(stepExecution);
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP_EXECUTION") != -1);
}
public void testModifiedFindStepExecutions(){
stepDao.setTablePrefix("FOO_");
stepDao.findStepExecutions(step);
stepExecutionDao.setTablePrefix("FOO_");
stepExecutionDao.findStepExecutions(step);
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP_EXECUTION") != -1);
}
public void testModifiedUpdateStep(){
stepDao.setTablePrefix("FOO_");
stepDao.updateStepInstance(step);
stepInstanceDao.setTablePrefix("FOO_");
stepInstanceDao.updateStepInstance(step);
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP") != -1);
}
public void testModifiedCreateStep(){
stepDao.setTablePrefix("FOO_");
stepInstanceDao.setTablePrefix("FOO_");
stepIncrementer.nextLongValue();
stepIncrementerControl.setReturnValue(1);
stepIncrementerControl.replay();
stepDao.createStepInstance(job, "test");
stepInstanceDao.createStepInstance(job, "test");
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP") != -1);
}
public void testModifiedFindSteps(){
stepDao.setTablePrefix("FOO_");
stepDao.findStepInstances(new JobInstance(new Long(1), new JobParameters()));
stepInstanceDao.setTablePrefix("FOO_");
stepInstanceDao.findStepInstances(new JobInstance(new Long(1), new JobParameters()));
assertTrue(jdbcTemplate.getSqlStatement().indexOf("FOO_STEP") != -1);
}
public void testModifiedFindStep(){
stepDao.setTablePrefix("FOO_");
stepInstanceDao.setTablePrefix("FOO_");
try{
stepDao.findStepInstance(job, "test");
stepInstanceDao.findStepInstance(job, "test");
}
catch(NullPointerException ex){
//It's going to throw a NullPointerException because the MockJdbcTemplate
@@ -115,7 +119,7 @@ public class JdbcStepDaoPrefixTests extends TestCase {
public void testDefaultFindStep(){
try{
stepDao.findStepInstance(job, "test");
stepInstanceDao.findStepInstance(job, "test");
}
catch(NullPointerException ex){
//It's going to throw a NullPointerException because the MockJdbcTemplate
@@ -127,7 +131,7 @@ public class JdbcStepDaoPrefixTests extends TestCase {
}
public void testDefaultFindSteps(){
stepDao.findStepInstances(new JobInstance(new Long(1), new JobParameters()));
stepInstanceDao.findStepInstances(new JobInstance(new Long(1), new JobParameters()));
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP") != -1);
}
@@ -135,17 +139,17 @@ public class JdbcStepDaoPrefixTests extends TestCase {
stepIncrementer.nextLongValue();
stepIncrementerControl.setReturnValue(1);
stepIncrementerControl.replay();
stepDao.createStepInstance(job, "test");
stepInstanceDao.createStepInstance(job, "test");
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP") != -1);
}
public void testDefaultUpdateStep(){
stepDao.updateStepInstance(step);
stepInstanceDao.updateStepInstance(step);
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP") != -1);
}
public void testDefaultFindStepExecutions(){
stepDao.findStepExecutions(step);
stepExecutionDao.findStepExecutions(step);
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP_EXECUTION") != -1);
}
@@ -153,12 +157,12 @@ public class JdbcStepDaoPrefixTests extends TestCase {
stepExecutionIncrementer.nextLongValue();
stepExecutionIncrementerControl.setReturnValue(1);
stepExecutionIncrementerControl.replay();
stepDao.saveStepExecution(stepExecution);
stepExecutionDao.saveStepExecution(stepExecution);
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP_EXECUTION") != -1);
}
public void testDefaultUpdateStepExecution(){
stepDao.updateStepExecution(stepExecution);
stepExecutionDao.updateStepExecution(stepExecution);
assertTrue(jdbcTemplate.getSqlStatement().indexOf("BATCH_STEP_EXECUTION") != -1);
}

View File

@@ -11,11 +11,13 @@ public class JdbcStepDaoTests extends AbstractStepDaoTests {
private static final String LONG_STRING = JdbcJobDaoTests.LONG_STRING;
protected void onSetUpBeforeTransaction() throws Exception {
((JdbcStepDao) stepDao).setTablePrefix(JdbcJobDao.DEFAULT_TABLE_PREFIX);
((JdbcStepInstanceDao) stepInstanceDao).setTablePrefix(JdbcJobDao.DEFAULT_TABLE_PREFIX);
((JdbcStepExecutionDao) stepExecutionDao).setTablePrefix(JdbcJobDao.DEFAULT_TABLE_PREFIX);
}
public void testTablePrefix() throws Exception {
((JdbcStepDao) stepDao).setTablePrefix("FOO_");
((JdbcStepInstanceDao) stepInstanceDao).setTablePrefix("FOO_");
((JdbcStepExecutionDao) stepExecutionDao).setTablePrefix("FOO_");
try {
testCreateStep();
fail("Expected DataAccessException");
@@ -28,7 +30,7 @@ public class JdbcStepDaoTests extends AbstractStepDaoTests {
assertTrue(LONG_STRING.length()>250);
stepExecution.setExitStatus(ExitStatus.FINISHED.addExitDescription(LONG_STRING));
stepDao.updateStepExecution(stepExecution);
stepExecutionDao.updateStepExecution(stepExecution);
List executions = jdbcTemplate.queryForList(
"SELECT * FROM BATCH_STEP_EXECUTION where STEP_INSTANCE_ID=?",

View File

@@ -202,7 +202,7 @@ public class SimpleStepExecutorTests extends TestCase {
public void testRepository() throws Exception {
SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapStepDao());
SimpleJobRepository repository = new SimpleJobRepository(new MapJobDao(), new MapStepDao(), new MapStepDao());
stepExecutor.setRepository(repository);
StepInstance step = new StepInstance(new Long(1));

View File

@@ -55,7 +55,7 @@ public class StepExecutorInterruptionTests extends TestCase {
public void setUp() throws Exception {
jobRepository = new SimpleJobRepository(jobDao, stepDao);
jobRepository = new SimpleJobRepository(jobDao, stepDao, stepDao);
JobSupport jobConfiguration = new JobSupport();
step = new RepeatOperationsStep();

View File

@@ -11,11 +11,16 @@
<property name="jobExecutionIncrementer" ref="jobExecutionIncrementer" />
</bean>
<bean id="stepDao" class="org.springframework.batch.execution.repository.dao.JdbcStepDao" >
<bean id="stepInstanceDao" class="org.springframework.batch.execution.repository.dao.JdbcStepInstanceDao" >
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="stepIncrementer" ref="stepIncrementer" />
<property name="stepIncrementer" ref="stepIncrementer" />
<property name="stepExecutionDao" ref="stepExecutionDao" />
</bean>
<bean id="stepExecutionDao" class="org.springframework.batch.execution.repository.dao.JdbcStepExecutionDao" >
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="stepExecutionIncrementer" ref="stepExecutionIncrementer" />
<property name="jobDao" ref="jobDao"/>
<property name="jobDao" ref="jobDao"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >

View File

@@ -46,6 +46,7 @@
<bean id="simpleJobRepository"
class="org.springframework.batch.execution.repository.SimpleJobRepository">
<constructor-arg ref="jobDao" />
<constructor-arg ref="stepDao" />
<constructor-arg ref="stepDao" />
</bean>