diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/AbstractJobExplorerFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/AbstractJobExplorerFactoryBean.java index 1db77387f..dcc383089 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/AbstractJobExplorerFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/AbstractJobExplorerFactoryBean.java @@ -17,6 +17,7 @@ package org.springframework.batch.core.explore.support; import org.springframework.batch.core.explore.JobExplorer; +import org.springframework.batch.core.repository.dao.ExecutionContextDao; import org.springframework.batch.core.repository.dao.JobExecutionDao; import org.springframework.batch.core.repository.dao.JobInstanceDao; import org.springframework.batch.core.repository.dao.StepExecutionDao; @@ -46,6 +47,8 @@ public abstract class AbstractJobExplorerFactoryBean implements FactoryBean { protected abstract StepExecutionDao createStepExecutionDao() throws Exception; + protected abstract ExecutionContextDao createExecutionContextDao() throws Exception; + /** * The type of object to be returned from {@link #getObject()}. * diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java index 86d4f8c00..72802acbb 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/JobExplorerFactoryBean.java @@ -19,18 +19,22 @@ package org.springframework.batch.core.explore.support; import javax.sql.DataSource; import org.springframework.batch.core.repository.dao.AbstractJdbcBatchMetadataDao; +import org.springframework.batch.core.repository.dao.ExecutionContextDao; +import org.springframework.batch.core.repository.dao.JdbcExecutionContextDao; import org.springframework.batch.core.repository.dao.JdbcJobExecutionDao; import org.springframework.batch.core.repository.dao.JdbcJobInstanceDao; import org.springframework.batch.core.repository.dao.JdbcStepExecutionDao; import org.springframework.batch.core.repository.dao.JobExecutionDao; import org.springframework.batch.core.repository.dao.JobInstanceDao; import org.springframework.batch.core.repository.dao.StepExecutionDao; +import org.springframework.batch.item.ExecutionContext; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.jdbc.core.simple.SimpleJdbcOperations; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; import org.springframework.jdbc.support.incrementer.AbstractDataFieldMaxValueIncrementer; import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer; +import org.springframework.jdbc.support.lob.LobHandler; import org.springframework.util.Assert; /** @@ -40,7 +44,8 @@ import org.springframework.util.Assert; * * @author Dave Syer */ -public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean implements InitializingBean { +public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean + implements InitializingBean { private DataSource dataSource; @@ -55,9 +60,13 @@ public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean imple } }; + private LobHandler lobHandler; + /** * Public setter for the {@link DataSource}. - * @param dataSource a {@link DataSource} + * + * @param dataSource + * a {@link DataSource} */ public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; @@ -65,12 +74,23 @@ public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean imple /** * Sets the table prefix for all the batch meta-data tables. + * * @param tablePrefix */ public void setTablePrefix(String tablePrefix) { this.tablePrefix = tablePrefix; } + /** + * The lob handler to use when saving {@link ExecutionContext} instances. + * Defaults to null which works for most databases. + * + * @param lobHandler + */ + public void setLobHandler(LobHandler lobHandler) { + this.lobHandler = lobHandler; + } + public void afterPropertiesSet() throws Exception { Assert.notNull(dataSource, "DataSource must not be null."); @@ -80,7 +100,19 @@ public class JobExplorerFactoryBean extends AbstractJobExplorerFactoryBean imple } private Object getTarget() throws Exception { - return new SimpleJobExplorer(createJobInstanceDao(), createJobExecutionDao(), createStepExecutionDao()); + return new SimpleJobExplorer(createJobInstanceDao(), + createJobExecutionDao(), createStepExecutionDao(), + createExecutionContextDao()); + } + + @Override + protected ExecutionContextDao createExecutionContextDao() throws Exception { + JdbcExecutionContextDao dao = new JdbcExecutionContextDao(); + dao.setJdbcTemplate(jdbcTemplate); + dao.setLobHandler(lobHandler); + dao.setTablePrefix(tablePrefix); + dao.afterPropertiesSet(); + return dao; } @Override diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/MapJobExplorerFactoryBean.java b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/MapJobExplorerFactoryBean.java index 8f2be18ea..20b9fefcf 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/MapJobExplorerFactoryBean.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/MapJobExplorerFactoryBean.java @@ -16,8 +16,10 @@ package org.springframework.batch.core.explore.support; +import org.springframework.batch.core.repository.dao.ExecutionContextDao; import org.springframework.batch.core.repository.dao.JobExecutionDao; import org.springframework.batch.core.repository.dao.JobInstanceDao; +import org.springframework.batch.core.repository.dao.MapExecutionContextDao; import org.springframework.batch.core.repository.dao.MapJobExecutionDao; import org.springframework.batch.core.repository.dao.MapJobInstanceDao; import org.springframework.batch.core.repository.dao.MapStepExecutionDao; @@ -47,8 +49,13 @@ public class MapJobExplorerFactoryBean extends AbstractJobExplorerFactoryBean { return new MapStepExecutionDao(); } + @Override + protected ExecutionContextDao createExecutionContextDao() throws Exception { + return new MapExecutionContextDao(); + } + public Object getObject() throws Exception { - return new SimpleJobExplorer(createJobInstanceDao(), createJobExecutionDao(), createStepExecutionDao()); + return new SimpleJobExplorer(createJobInstanceDao(), createJobExecutionDao(), createStepExecutionDao(), createExecutionContextDao()); } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/SimpleJobExplorer.java b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/SimpleJobExplorer.java index 269224f02..9d43dbedd 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/SimpleJobExplorer.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/explore/support/SimpleJobExplorer.java @@ -23,6 +23,7 @@ import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.explore.JobExplorer; +import org.springframework.batch.core.repository.dao.ExecutionContextDao; import org.springframework.batch.core.repository.dao.JobExecutionDao; import org.springframework.batch.core.repository.dao.JobInstanceDao; import org.springframework.batch.core.repository.dao.StepExecutionDao; @@ -50,6 +51,8 @@ public class SimpleJobExplorer implements JobExplorer { private StepExecutionDao stepExecutionDao; + private ExecutionContextDao ecDao; + /** * Provide default constructor with low visibility in case user wants to use * use aop:proxy-target-class="true" for AOP interceptor. @@ -57,11 +60,12 @@ public class SimpleJobExplorer implements JobExplorer { SimpleJobExplorer() { } - public SimpleJobExplorer(JobInstanceDao jobInstanceDao, JobExecutionDao jobExecutionDao, StepExecutionDao stepExecutionDao) { + public SimpleJobExplorer(JobInstanceDao jobInstanceDao, JobExecutionDao jobExecutionDao, StepExecutionDao stepExecutionDao, ExecutionContextDao ecDao) { super(); this.jobInstanceDao = jobInstanceDao; this.jobExecutionDao = jobExecutionDao; this.stepExecutionDao = stepExecutionDao; + this.ecDao = ecDao; } /* (non-Javadoc) @@ -102,7 +106,9 @@ public class SimpleJobExplorer implements JobExplorer { * @see org.springframework.batch.core.explore.JobExplorer#getStepExecution(java.lang.Long) */ public StepExecution getStepExecution(Long jobExecutionId, Long executionId) { - return stepExecutionDao.getStepExecution(getJobExecution(jobExecutionId), executionId); + StepExecution stepExecution = stepExecutionDao.getStepExecution(getJobExecution(jobExecutionId), executionId); + getStepExecutionDependencies(stepExecution); + return stepExecution; } /* (non-Javadoc) @@ -128,6 +134,12 @@ public class SimpleJobExplorer implements JobExplorer { JobInstance jobInstance = jobInstanceDao.getJobInstance(jobExecution); stepExecutionDao.addStepExecutions(jobExecution); jobExecution.setJobInstance(jobInstance); + jobExecution.setExecutionContext(ecDao.getExecutionContext(jobExecution)); + + } + + private void getStepExecutionDependencies(StepExecution stepExecution) { + stepExecution.setExecutionContext(ecDao.getExecutionContext(stepExecution)); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/exlore/support/SimpleJobExplorerTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/exlore/support/SimpleJobExplorerTests.java index 9441c9e13..7277af07f 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/exlore/support/SimpleJobExplorerTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/exlore/support/SimpleJobExplorerTests.java @@ -31,7 +31,9 @@ import org.junit.Test; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; import org.springframework.batch.core.JobParameters; +import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.explore.support.SimpleJobExplorer; +import org.springframework.batch.core.repository.dao.ExecutionContextDao; import org.springframework.batch.core.repository.dao.JobExecutionDao; import org.springframework.batch.core.repository.dao.JobInstanceDao; import org.springframework.batch.core.repository.dao.StepExecutionDao; @@ -44,25 +46,28 @@ import org.springframework.batch.core.repository.dao.StepExecutionDao; */ public class SimpleJobExplorerTests extends TestCase { - SimpleJobExplorer jobExplorer; + private SimpleJobExplorer jobExplorer; - JobExecutionDao jobExecutionDao; + private JobExecutionDao jobExecutionDao; - JobInstanceDao jobInstanceDao; + private JobInstanceDao jobInstanceDao; - StepExecutionDao stepExecutionDao; + private StepExecutionDao stepExecutionDao; - JobInstance jobInstance = new JobInstance(111L, new JobParameters(), "job"); + private JobInstance jobInstance = new JobInstance(111L, new JobParameters(), "job"); - JobExecution jobExecution = new JobExecution(jobInstance, 123L); + private ExecutionContextDao ecDao; + + private JobExecution jobExecution = new JobExecution(jobInstance, 123L); public void setUp() throws Exception { jobExecutionDao = createMock(JobExecutionDao.class); jobInstanceDao = createMock(JobInstanceDao.class); stepExecutionDao = createMock(StepExecutionDao.class); + ecDao = createMock(ExecutionContextDao.class); - jobExplorer = new SimpleJobExplorer(jobInstanceDao, jobExecutionDao, stepExecutionDao); + jobExplorer = new SimpleJobExplorer(jobInstanceDao, jobExecutionDao, stepExecutionDao, ecDao); } @@ -88,12 +93,15 @@ public class SimpleJobExplorerTests extends TestCase { @Test public void testGetStepExecution() throws Exception { expect(jobExecutionDao.getJobExecution(123L)).andReturn(jobExecution); - expect(stepExecutionDao.getStepExecution(jobExecution, 123L)).andReturn(null); + StepExecution stepExecution = jobExecution.createStepExecution("foo"); + expect(stepExecutionDao.getStepExecution(jobExecution, 123L)).andReturn(stepExecution); + expect(ecDao.getExecutionContext(jobExecution)).andReturn(null); + expect(ecDao.getExecutionContext(stepExecution)).andReturn(null); stepExecutionDao.addStepExecutions(jobExecution); expectLastCall(); - replay(jobExecutionDao, stepExecutionDao); + replay(jobExecutionDao, stepExecutionDao, ecDao); jobExplorer.getStepExecution(jobExecution.getId(), 123L); - verify(jobExecutionDao, stepExecutionDao); + verify(jobExecutionDao, stepExecutionDao, ecDao); } @Test