From 5fa4ffc3b2e72701f80f5252c5622c2ecc950344 Mon Sep 17 00:00:00 2001 From: dsyer Date: Tue, 11 Dec 2007 18:10:20 +0000 Subject: [PATCH] IN PROGRESS - issue BATCH-127: Allow job configuration to control re-entrant behavior http://opensource.atlassian.com/projects/spring/browse/BATCH-127 Refactor JobRepository.findOrCreateJob() to return JobExecution. --- .../batch/core/domain/JobExecution.java | 8 + .../JobExecutionAlreadyRunningException.java | 2 +- .../batch/core/repository/JobRepository.java | 12 +- .../batch/core/domain/JobExecutionTests.java | 9 + ...ExecutionAlreadyRunningExceptionTests.java | 4 +- .../execution/launch/JobExecutorFacade.java | 1 + .../batch/execution/launch/JobLauncher.java | 1 + .../launch/SimpleJobExecutorFacade.java | 10 +- .../execution/launch/SimpleJobLauncher.java | 1 + .../repository/SimpleJobRepository.java | 157 ++++++++++++------ .../execution/repository/dao/JobDao.java | 10 +- .../job/DefaultJobExecutorTests.java | 5 +- .../launch/SimpleJobExecutorFacadeTests.java | 17 +- .../execution/launch/SimpleJobTests.java | 12 +- .../launch/TaskExecutorJobLauncherTests.java | 1 + .../repository/SimpleJobRepositoryTests.java | 93 +++++++++-- .../step/simple/JobRepositorySupport.java | 2 +- .../simple/StepExecutorInterruptionTests.java | 4 +- .../.settings/hsql-manager.launch | 2 +- .../.settings/hsql-server.launch | 2 +- .../.settings/jmxLauncher.launch | 14 ++ .../.settings/jobLauncher.launch | 2 +- .../src/main/resources/batch.properties | 4 +- .../main/resources/business-schema-db2.sql | 11 +- .../main/resources/business-schema-derby.sql | 11 +- .../main/resources/business-schema-hsqldb.sql | 5 +- .../resources/business-schema-oracle10g.sql | 11 +- .../resources/business-schema-postgresql.sql | 11 +- .../src/main/resources/jobs/footballJob.xml | 23 +-- .../src/main/sql/init.sql.vpp | 4 +- .../batch/sample/TaskExecutorLauncher.java | 4 +- 31 files changed, 296 insertions(+), 157 deletions(-) rename {spring-batch-execution/src/main/java/org/springframework/batch/execution/launch => spring-batch-core/src/main/java/org/springframework/batch/core/repository}/JobExecutionAlreadyRunningException.java (91%) rename {spring-batch-execution/src/test/java/org/springframework/batch/execution/launch => spring-batch-core/src/test/java/org/springframework/batch/core/repository}/JobExecutionAlreadyRunningExceptionTests.java (88%) create mode 100644 spring-batch-samples/.settings/jmxLauncher.launch diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobExecution.java index 75049ff0d..98fc21c6d 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobExecution.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobExecution.java @@ -234,4 +234,12 @@ public class JobExecution extends Entity { public String toString() { return super.toString()+", job=["+job+"]"; } + + /** + * Test if this {@link JobExecution} indicates that it is running. + * @return true if the end time is null + */ + public boolean isRunning() { + return endTime==null; + } } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobExecutionAlreadyRunningException.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobExecutionAlreadyRunningException.java similarity index 91% rename from spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobExecutionAlreadyRunningException.java rename to spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobExecutionAlreadyRunningException.java index 18e538e2a..58df8ac05 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobExecutionAlreadyRunningException.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobExecutionAlreadyRunningException.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.batch.execution.launch; +package org.springframework.batch.core.repository; import org.springframework.batch.core.executor.JobExecutionException; diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobRepository.java b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobRepository.java index 9aa73c013..b4e473161 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobRepository.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/repository/JobRepository.java @@ -47,7 +47,7 @@ import org.springframework.batch.core.domain.StepInstance; public interface JobRepository { /** - * Find or create a job for a given {@link JobIdentifier} and configuration. + * Find or create a job execution for a given {@link JobIdentifier} and configuration. * If the job that is uniquely identified by {@link JobIdentifier} already * exists, its persisted values (including ID) will be returned in a new * {@link JobInstance} object. If no previous run is found, a new job will @@ -59,11 +59,15 @@ public interface JobRepository { * identifies this particular run of the configuration across * possible restarts * - * @return a valid job + * @return a valid job execution for the identifier provided + * @throws JobExecutionAlreadyRunningException + * if there is a {@link JobExecution} alrady running for the + * job instance that would otherwise be returned * */ - public JobInstance findOrCreateJob(JobConfiguration jobConfiguration, - JobIdentifier jobIdentifier); + public JobExecution findOrCreateJob(JobConfiguration jobConfiguration, + JobIdentifier jobIdentifier) + throws JobExecutionAlreadyRunningException; /** * Update a Job. diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java index 2a488b0f1..d33021b02 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java @@ -48,6 +48,15 @@ public class JobExecutionTests extends TestCase { assertEquals(100L, execution.getEndTime().getTime()); } + /** + * Test method for {@link org.springframework.batch.core.domain.JobExecution#getEndTime()}. + */ + public void testIsRunning() { + assertTrue(execution.isRunning()); + execution.setEndTime(new Timestamp(100L)); + assertFalse(execution.isRunning()); + } + /** * Test method for {@link org.springframework.batch.core.domain.JobExecution#getStartTime()}. */ diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/JobExecutionAlreadyRunningExceptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/JobExecutionAlreadyRunningExceptionTests.java similarity index 88% rename from spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/JobExecutionAlreadyRunningExceptionTests.java rename to spring-batch-core/src/test/java/org/springframework/batch/core/repository/JobExecutionAlreadyRunningExceptionTests.java index 49ac78fb6..10ac6053f 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/JobExecutionAlreadyRunningExceptionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/repository/JobExecutionAlreadyRunningExceptionTests.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.batch.execution.launch; +package org.springframework.batch.core.repository; -import org.springframework.batch.execution.AbstractExceptionTests; +import org.springframework.batch.core.AbstractExceptionTests; /** * @author Dave Syer diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobExecutorFacade.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobExecutorFacade.java index 89f44b0b4..dfa2a0de2 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobExecutorFacade.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobExecutorFacade.java @@ -19,6 +19,7 @@ package org.springframework.batch.execution.launch; import org.springframework.batch.core.configuration.NoSuchJobConfigurationException; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobIdentifier; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; /** * Interface which defines a facade for running jobs. The interface is diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobLauncher.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobLauncher.java index 09e7fa6c1..2f9dd8bd0 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobLauncher.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/JobLauncher.java @@ -18,6 +18,7 @@ package org.springframework.batch.execution.launch; import org.springframework.batch.core.configuration.NoSuchJobConfigurationException; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobIdentifier; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; /** * Simple interface for controlling jobs, including possible ad-hoc executions, diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacade.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacade.java index 742720498..5dff00a56 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacade.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacade.java @@ -29,8 +29,8 @@ import org.springframework.batch.core.configuration.JobConfigurationLocator; import org.springframework.batch.core.configuration.NoSuchJobConfigurationException; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobIdentifier; -import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.executor.JobExecutor; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.execution.job.DefaultJobExecutor; import org.springframework.batch.repeat.RepeatContext; @@ -164,15 +164,9 @@ class SimpleJobExecutorFacade implements JobExecutorFacade, JobConfiguration jobConfiguration = jobConfigurationLocator .getJobConfiguration(jobIdentifier.getName()); - JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, + return jobRepository.findOrCreateJob(jobConfiguration, jobIdentifier); - JobExecution execution = job.createNewJobExecution(); - // Save the JobExecution so that it picks up an ID (useful for clients - // monitoring asynchronous executions): - jobRepository.saveOrUpdate(execution); - - return execution; } /** diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobLauncher.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobLauncher.java index 781092a35..74af6b791 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobLauncher.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/launch/SimpleJobLauncher.java @@ -33,6 +33,7 @@ import org.springframework.batch.core.configuration.NoSuchJobConfigurationExcept import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobIdentifier; import org.springframework.batch.core.executor.JobExecutor; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.runtime.JobIdentifierFactory; import org.springframework.batch.execution.job.DefaultJobExecutor; 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 4f7fdeba5..afdb0192e 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 @@ -29,6 +29,7 @@ import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; import org.springframework.batch.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; @@ -36,18 +37,18 @@ import org.springframework.batch.restart.GenericRestartData; import org.springframework.util.Assert; /** - * + * *

* Simple Job Repository that stores Jobs, JobExecutions, Steps, and * StepExecutions using the provided JobDao and StepDao. *

- * + * * @author Lucas Ward * @author Dave Syer * @see JobRepository * @see StepDao * @see JobDao - * + * */ public class SimpleJobRepository implements JobRepository { @@ -71,7 +72,7 @@ public class SimpleJobRepository implements JobRepository { * either creating a new job or finding an existing one, which will ensure * that the id field of the job is populated with the correct value. *

- * + * *

* 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 @@ -82,20 +83,23 @@ public class SimpleJobRepository implements JobRepository { * (there must be at least 1) and it will be returned. If no job is found, a * new one will be created based on the configuration. *

- * + * @throws JobExecutionAlreadyRunningException + * * @see JobRepository#findOrCreateJob(JobConfiguration, JobIdentifier) - * @throws BatchRestartException if more than one JobInstance if found - * or if JobInstance.getJobExecutionCount() is greater than JobConfiguration.getStartLimit() + * @throws BatchRestartException + * if more than one JobInstance if found or if + * JobInstance.getJobExecutionCount() is greater than + * JobConfiguration.getStartLimit() */ - public JobInstance findOrCreateJob(JobConfiguration jobConfiguration, JobIdentifier runtimeInformation) { + public JobExecution findOrCreateJob(JobConfiguration jobConfiguration, + JobIdentifier runtimeInformation) throws JobExecutionAlreadyRunningException { List jobs; // Check if a job is restartable, if not, create and return a new job if (jobConfiguration.isRestartable() == false) { return createJob(jobConfiguration, runtimeInformation); - } - else { + } else { // find all jobs matching the runtime information. jobs = jobDao.findJobs(runtimeInformation); } @@ -103,24 +107,48 @@ public class SimpleJobRepository implements JobRepository { if (jobs.size() == 1) { // One job was found JobInstance job = (JobInstance) jobs.get(0); - job.setSteps(findSteps(jobConfiguration.getStepConfigurations(), job)); + job.setSteps(findSteps(jobConfiguration.getStepConfigurations(), + job)); job.setJobExecutionCount(jobDao.getJobExecutionCount(job.getId())); if (job.getJobExecutionCount() > jobConfiguration.getStartLimit()) { - throw new BatchRestartException("Restart Max exceeded for Job: " + job.toString()); + throw new BatchRestartException( + "Restart Max exceeded for Job: " + job.toString()); } - return job; - } - else if (jobs.size() == 0) { + List executions = jobDao.findJobExecutions(job); + for (Iterator iterator = executions.iterator(); iterator.hasNext();) { + JobExecution execution = (JobExecution) iterator.next(); + if (execution.isRunning()) { + throw new JobExecutionAlreadyRunningException("A job execution for this job is already running: "+job); + } + } + /* + * Update the job, then if this method is transactional, and the + * isolation level is SERIALIZABLE, another launcher trying to start + * the same job in another thread or process will lose. + */ + jobDao.update(job); + + return generateJobExecution(job); + + } else if (jobs.size() == 0) { // no job found, create one return createJob(jobConfiguration, runtimeInformation); - } - else { + } else { // More than one job found, throw exception - throw new BatchRestartException("Error restarting job, more than one JobInstance found for: " - + jobConfiguration.toString()); + throw new BatchRestartException( + "Error restarting job, more than one JobInstance found for: " + + jobConfiguration.toString()); } } + private JobExecution generateJobExecution(JobInstance job) { + JobExecution execution = job.createNewJobExecution(); + // Save the JobExecution so that it picks up an ID (useful for clients + // monitoring asynchronous executions): + saveOrUpdate(execution); + return execution; + } + /** * Save or Update a JobExecution. A JobExecution is considered one * 'execution' of a particular job. Therefore, it must have it's jobId field @@ -128,20 +156,22 @@ public class SimpleJobRepository implements JobRepository { * identifer, because it must be updatable separately. If an id isn't found, * a new JobExecution is created, if one is found, the current row is * updated. - * - * @param JobExecution to be stored. - * @throws IllegalArgumentException if jobExecution is null. + * + * @param JobExecution + * to be stored. + * @throws IllegalArgumentException + * if jobExecution is null. */ public void saveOrUpdate(JobExecution jobExecution) { Assert.notNull(jobExecution, "JobExecution cannot be null."); - Assert.notNull(jobExecution.getJobId(), "JobExecution must have a Job ID set."); + Assert.notNull(jobExecution.getJobId(), + "JobExecution must have a Job ID set."); if (jobExecution.getId() == null) { // existing instance jobDao.save(jobExecution); - } - else { + } else { // new execution jobDao.update(jobExecution); } @@ -151,15 +181,20 @@ public class SimpleJobRepository implements JobRepository { * Update an existing job. A job must have been obtained from the * findOrCreateJob method, otherwise it is likely that the id is incorrect * or non-existant. - * - * @param job to be updated. - * @throws IllegalArgumentException if Job or it's Id is null. + * + * @param job + * to be updated. + * @throws IllegalArgumentException + * if Job or it's Id is null. */ public void update(JobInstance job) { Assert.notNull(job, "Job cannot be null."); - Assert.notNull(job.getId(), "Job cannot be updated if it's ID is null. It must be obtained" - + "from SimpleJobRepository.findOrCreateJob to be considered valid."); + Assert + .notNull( + job.getId(), + "Job cannot be updated if it's ID is null. It must be obtained" + + "from SimpleJobRepository.findOrCreateJob to be considered valid."); jobDao.update(job); } @@ -169,20 +204,22 @@ public class SimpleJobRepository implements JobRepository { * saved and an id will be set, otherwise it will be updated. It should be * noted that assigning an ID randomly will likely cause an exception * depending on the StepDao implementation. - * - * @param StepExecution to be saved. - * @throws IllegalArgumentException if stepExecution is null. + * + * @param StepExecution + * to be saved. + * @throws IllegalArgumentException + * if stepExecution is null. */ public void saveOrUpdate(StepExecution stepExecution) { Assert.notNull(stepExecution, "StepExecution cannot be null."); - Assert.notNull(stepExecution.getStepId(), "StepExecution's Step Id cannot be null."); + Assert.notNull(stepExecution.getStepId(), + "StepExecution's Step Id cannot be null."); if (stepExecution.getId() == null) { // new execution, obtain id and insert stepDao.save(stepExecution); - } - else { + } else { // existing execution, update stepDao.update(stepExecution); } @@ -190,15 +227,20 @@ public class SimpleJobRepository implements JobRepository { /** * Update the given step. - * - * @param StepInstance to be updated. - * @throws IllegalArgumentException if step or it's id is null. + * + * @param StepInstance + * to be updated. + * @throws IllegalArgumentException + * if step or it's id is null. */ public void update(StepInstance step) { Assert.notNull(step, "Step cannot be null."); - 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."); + 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.update(step); @@ -209,11 +251,15 @@ public class SimpleJobRepository implements JobRepository { * calling {@link JobDao#createJob(JobRuntimeInformation)} and then it's * list of StepConfigurations is passed to the createSteps method. */ - private JobInstance createJob(JobConfiguration jobConfiguration, JobIdentifier runtimeInformation) { + private JobExecution createJob(JobConfiguration jobConfiguration, + JobIdentifier runtimeInformation) { JobInstance job = jobDao.createJob(runtimeInformation); - job.setSteps(createSteps(job, jobConfiguration.getStepConfigurations())); - return job; + job + .setSteps(createSteps(job, jobConfiguration + .getStepConfigurations())); + JobExecution execution = generateJobExecution(job); + return execution; } /* @@ -225,9 +271,11 @@ public class SimpleJobRepository implements JobRepository { Iterator i = stepConfigurations.iterator(); while (i.hasNext()) { StepConfiguration stepConfiguration = (StepConfiguration) i.next(); - StepInstance step = stepDao.createStep(job, stepConfiguration.getName()); - //Ensure valid restart data is being returned. - if(step.getRestartData() == null || step.getRestartData().getProperties() == null){ + StepInstance step = stepDao.createStep(job, stepConfiguration + .getName()); + // Ensure valid restart data is being returned. + if (step.getRestartData() == null + || step.getRestartData().getProperties() == null) { step.setRestartData(new GenericRestartData(new Properties())); } steps.add(step); @@ -245,13 +293,18 @@ public class SimpleJobRepository implements JobRepository { while (i.hasNext()) { StepConfiguration stepConfiguration = (StepConfiguration) i.next(); - StepInstance step = stepDao.findStep(job, stepConfiguration.getName()); + StepInstance step = stepDao.findStep(job, stepConfiguration + .getName()); if (step != null) { - step.setStepExecutionCount(stepDao.getStepExecutionCount(step.getId())); - //Ensure valid restart data is being returned. - if(step.getRestartData() == null || step.getRestartData().getProperties() == null){ - step.setRestartData(new GenericRestartData(new Properties())); + step.setStepExecutionCount(stepDao.getStepExecutionCount(step + .getId())); + // Ensure valid restart data is being returned. + if (step.getRestartData() == null + || step.getRestartData().getProperties() == null) { + step + .setRestartData(new GenericRestartData( + new Properties())); } steps.add(step); } 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 fb96dcca5..5781cfd41 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 @@ -26,14 +26,15 @@ import org.springframework.batch.core.domain.JobInstance; * Data Access Object for jobs. * * @author Lucas Ward - * + * */ public interface JobDao { /** * Create a job using the provided JobIdentifier as the natural key. * - * PostConditions: A valid job will be returned which contains an unique Id. + * PostConditions: A valid job will be returned which has been persisted and + * contains an unique Id. * * @param jobIdentifier * @return Job @@ -45,7 +46,8 @@ public interface JobDao { * Identifier are found, then a list of size 0 will be returned. * * @param jobIdentifier - * @return List of {@link JobInstance} objects matching {@link JobIdentifier} + * @return List of {@link JobInstance} objects matching + * {@link JobIdentifier} */ public List findJobs(JobIdentifier jobIdentifier); @@ -85,7 +87,7 @@ public interface JobDao { * @param job */ public int getJobExecutionCount(Long jobId); - + /** * Return list of JobExecutions for given job. * diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java index 6f38d9ad1..16136cda7 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/DefaultJobExecutorTests.java @@ -128,9 +128,8 @@ public class DefaultJobExecutorTests extends TestCase { jobIdentifer = new SimpleJobIdentifier("TestJob"); - job = jobRepository.findOrCreateJob(jobConfiguration, jobIdentifer); - - jobExecution = new JobExecution(job); + jobExecution = jobRepository.findOrCreateJob(jobConfiguration, jobIdentifer); + job = jobExecution.getJob(); List steps = job.getSteps(); step1 = (StepInstance) steps.get(0); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacadeTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacadeTests.java index 19dfc12b4..33790750a 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacadeTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/SimpleJobExecutorFacadeTests.java @@ -24,7 +24,6 @@ import java.util.Properties; import junit.framework.TestCase; -import org.easymock.AbstractMatcher; import org.easymock.MockControl; import org.springframework.batch.core.configuration.JobConfiguration; import org.springframework.batch.core.configuration.JobConfigurationLocator; @@ -32,6 +31,7 @@ import org.springframework.batch.core.configuration.NoSuchJobConfigurationExcept import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.executor.JobExecutor; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.runtime.SimpleJobIdentifier; import org.springframework.batch.io.exception.BatchCriticalException; @@ -97,7 +97,7 @@ public class SimpleJobExecutorFacadeTests extends TestCase { } private JobInstance setUpFacadeForNormalStart() - throws NoSuchJobConfigurationException { + throws Exception { jobIdentifier = new SimpleJobIdentifier("bar"); jobExecutor = new JobExecutor() { public ExitStatus run(JobConfiguration configuration, @@ -110,18 +110,7 @@ public class SimpleJobExecutorFacadeTests extends TestCase { JobInstance job = new JobInstance(jobIdentifier); jobExecution = new JobExecution(job); jobRepository.findOrCreateJob(jobConfiguration, jobIdentifier); - jobRepositoryControl.setReturnValue(job); - jobRepository.saveOrUpdate(jobExecution); - jobRepositoryControl.setMatcher(new AbstractMatcher() { - protected boolean argumentMatches(Object expected, Object actual) { - if (actual instanceof JobExecution) { - jobExecution = (JobExecution) actual; - return true; - } else { - return super.argumentMatches(expected, actual); - } - } - }); + jobRepositoryControl.setReturnValue(jobExecution); jobRepositoryControl.replay(); jobExecutorFacade .setJobConfigurationLocator(new JobConfigurationLocator() { 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 2630dff6a..dd9360e6f 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 @@ -118,7 +118,7 @@ public class SimpleJobTests extends TestCase { jobConfiguration.addStep(new SimpleStepConfiguration(getTasklet("foo", "bar"))); jobConfiguration.addStep(new SimpleStepConfiguration(getTasklet("spam"))); - JobInstance job = repository.findOrCreateJob(jobConfiguration, runtimeInformation); + JobInstance job = repository.findOrCreateJob(jobConfiguration, runtimeInformation).getJob(); assertEquals(job.getName(), "real.job"); @@ -169,8 +169,8 @@ public class SimpleJobTests extends TestCase { }); jobConfiguration.addStep(step); - JobInstance job = repository.findOrCreateJob(jobConfiguration, runtimeInformation); - JobExecution jobExecution = new JobExecution(job); + JobExecution jobExecution = repository.findOrCreateJob(jobConfiguration, runtimeInformation); + JobInstance job = jobExecution.getJob(); jobExecutor.run(jobConfiguration, jobExecution); assertEquals(BatchStatus.COMPLETED, job.getStatus()); @@ -193,10 +193,10 @@ public class SimpleJobTests extends TestCase { }); jobConfiguration.addStep(step); - JobInstance job = repository.findOrCreateJob(jobConfiguration, runtimeInformation); - JobExecution jobExecutionContext = new JobExecution(job); + JobExecution jobExecution = repository.findOrCreateJob(jobConfiguration, runtimeInformation); + JobInstance job = jobExecution.getJob(); try { - jobExecutor.run(jobConfiguration, jobExecutionContext); + jobExecutor.run(jobConfiguration, jobExecution); fail("Expected RuntimeException"); } catch (RuntimeException e) { diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/TaskExecutorJobLauncherTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/TaskExecutorJobLauncherTests.java index 03bc0e363..58eaf9807 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/TaskExecutorJobLauncherTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/launch/TaskExecutorJobLauncherTests.java @@ -30,6 +30,7 @@ import org.springframework.batch.core.configuration.NoSuchJobConfigurationExcept import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobIdentifier; import org.springframework.batch.core.domain.JobInstance; +import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; import org.springframework.batch.core.runtime.SimpleJobIdentifier; import org.springframework.batch.core.runtime.SimpleJobIdentifierFactory; import org.springframework.batch.repeat.ExitStatus; 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 bc29b15ab..8be90e01b 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 @@ -17,11 +17,13 @@ package org.springframework.batch.execution.repository; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; +import org.easymock.ArgumentsMatcher; import org.easymock.MockControl; import org.springframework.batch.core.configuration.JobConfiguration; import org.springframework.batch.core.configuration.StepConfiguration; @@ -74,6 +76,8 @@ public class SimpleJobRepositoryTests extends TestCase { List steps; + private JobExecution jobExecution; + public void setUp() throws Exception { jobDao = (JobDao) jobDaoControl.getMock(); @@ -96,8 +100,13 @@ public class SimpleJobRepositoryTests extends TestCase { stepConfigurations.add(stepConfiguration2); jobConfiguration.setSteps(stepConfigurations); - - databaseJob = new JobInstance(jobRuntimeInformation, new Long(1)); + + databaseJob = new JobInstance(jobRuntimeInformation, new Long(1)) { + public JobExecution createNewJobExecution() { + jobExecution = super.createNewJobExecution(); + return jobExecution; + } + }; databaseStep1 = new StepInstance(new Long(1)); databaseStep2 = new StepInstance(new Long(2)); @@ -110,7 +119,7 @@ public class SimpleJobRepositoryTests extends TestCase { /* * Test a restartable job, that has not been run before. */ - public void testCreateRestartableJob(){ + public void testCreateRestartableJob() throws Exception { List jobs = new ArrayList(); @@ -122,9 +131,18 @@ public class SimpleJobRepositoryTests extends TestCase { stepDaoControl.setReturnValue(databaseStep1); stepDao.createStep(databaseJob, "TestStep2"); stepDaoControl.setReturnValue(databaseStep2); + jobDao.save(new JobExecution(databaseJob)); + jobDaoControl.setMatcher(new ArgumentsMatcher(){ + public boolean matches(Object[] expected, Object[] actual) { + return ((JobExecution) actual[0]).getJob().equals(databaseJob); + } + public String toString(Object[] arguments) { + return ""+arguments[0]; + } + }); stepDaoControl.replay(); jobDaoControl.replay(); - JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation); + JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJob(); assertTrue(job.equals(databaseJob)); List jobSteps = job.getSteps(); Iterator it = jobSteps.iterator(); @@ -134,7 +152,7 @@ public class SimpleJobRepositoryTests extends TestCase { assertTrue(step.equals(databaseStep2)); } - public void testRestartedJob(){ + public void testRestartedJob() throws Exception{ List jobs = new ArrayList(); jobDao.findJobs(jobRuntimeInformation); jobs.add(databaseJob); @@ -150,8 +168,24 @@ public class SimpleJobRepositoryTests extends TestCase { stepDaoControl.replay(); jobDao.getJobExecutionCount(databaseJob.getId()); jobDaoControl.setReturnValue(1); + jobDao.findJobExecutions(databaseJob); + final List executions = new ArrayList(); + jobDaoControl.setReturnValue(executions); + jobDao.update(databaseJob); + jobDao.save(new JobExecution(databaseJob)); + jobDaoControl.setMatcher(new ArgumentsMatcher(){ + public boolean matches(Object[] expected, Object[] actual) { + JobExecution execution = (JobExecution) actual[0]; + executions.add(execution); + return execution.getJob().equals(databaseJob); + } + public String toString(Object[] arguments) { + return ""+arguments[0]; + } + }); + jobDaoControl.setVoidCallable(); jobDaoControl.replay(); - JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation); + JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJob(); assertTrue(job.equals(databaseJob)); List jobSteps = job.getSteps(); Iterator it = jobSteps.iterator(); @@ -164,7 +198,7 @@ public class SimpleJobRepositoryTests extends TestCase { } //Test that a restartable job that has multiple instances throws an exception. - public void testFindRestartableJobWithMultipleInstances(){ + public void testFindRestartableJobWithMultipleInstances() throws Exception{ List jobs = new ArrayList(); jobs.add(databaseJob); @@ -183,7 +217,7 @@ public class SimpleJobRepositoryTests extends TestCase { jobDaoControl.verify(); } - public void testRestartJobStartLimitExceeded(){ + public void testRestartJobStartLimitExceeded() throws Exception{ jobConfiguration.setStartLimit(1); @@ -216,7 +250,7 @@ public class SimpleJobRepositoryTests extends TestCase { stepDaoControl.verify(); } - public void testCreateNonRestartableJob(){ + public void testCreateNonRestartableJob() throws Exception{ List jobs = new ArrayList(); jobConfiguration.setRestartable(false); @@ -229,9 +263,18 @@ public class SimpleJobRepositoryTests extends TestCase { stepDaoControl.setReturnValue(databaseStep1); stepDao.createStep(databaseJob, "TestStep2"); stepDaoControl.setReturnValue(databaseStep2); + jobDao.save(new JobExecution(databaseJob)); + jobDaoControl.setMatcher(new ArgumentsMatcher(){ + public boolean matches(Object[] expected, Object[] actual) { + return ((JobExecution) actual[0]).getJob().equals(databaseJob); + } + public String toString(Object[] arguments) { + return ""+arguments[0]; + } + }); stepDaoControl.replay(); jobDaoControl.replay(); - JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation); + JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJob(); assertTrue(job.equals(databaseJob)); List jobSteps = job.getSteps(); Iterator it = jobSteps.iterator(); @@ -347,7 +390,7 @@ public class SimpleJobRepositoryTests extends TestCase { * Test to ensure that if a StepDao returns invalid * restart data, it is corrected. */ - public void testCreateStepsFixesInvalidRestartData(){ + public void testCreateStepsFixesInvalidRestartData() throws Exception{ List jobs = new ArrayList(); @@ -361,9 +404,18 @@ public class SimpleJobRepositoryTests extends TestCase { stepDao.createStep(databaseJob, "TestStep2"); databaseStep2.setRestartData(new GenericRestartData(null)); stepDaoControl.setReturnValue(databaseStep2); + jobDao.save(new JobExecution(databaseJob)); + jobDaoControl.setMatcher(new ArgumentsMatcher(){ + public boolean matches(Object[] expected, Object[] actual) { + return ((JobExecution) actual[0]).getJob().equals(databaseJob); + } + public String toString(Object[] arguments) { + return ""+arguments[0]; + } + }); stepDaoControl.replay(); jobDaoControl.replay(); - JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation); + JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJob(); List jobSteps = job.getSteps(); Iterator it = jobSteps.iterator(); StepInstance step = (StepInstance) it.next(); @@ -374,7 +426,7 @@ public class SimpleJobRepositoryTests extends TestCase { assertTrue(step.getRestartData().getProperties().isEmpty()); } - public void testFindStepsFixesInvalidRestartData(){ + public void testFindStepsFixesInvalidRestartData() throws Exception{ List jobs = new ArrayList(); jobDao.findJobs(jobRuntimeInformation); jobs.add(databaseJob); @@ -392,8 +444,21 @@ public class SimpleJobRepositoryTests extends TestCase { stepDaoControl.replay(); jobDao.getJobExecutionCount(databaseJob.getId()); jobDaoControl.setReturnValue(1); + jobDao.findJobExecutions(databaseJob); + jobDaoControl.setReturnValue(new ArrayList()); + jobDao.update(databaseJob); + jobDaoControl.setVoidCallable(); + jobDao.save(new JobExecution(databaseJob)); + jobDaoControl.setMatcher(new ArgumentsMatcher(){ + public boolean matches(Object[] expected, Object[] actual) { + return ((JobExecution) actual[0]).getJob().equals(databaseJob); + } + public String toString(Object[] arguments) { + return ""+arguments[0]; + } + }); jobDaoControl.replay(); - JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation); + JobInstance job = jobRepository.findOrCreateJob(jobConfiguration, jobRuntimeInformation).getJob(); assertTrue(job.equals(databaseJob)); List jobSteps = job.getSteps(); Iterator it = jobSteps.iterator(); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/JobRepositorySupport.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/JobRepositorySupport.java index 51562f2fe..9354ec3fb 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/JobRepositorySupport.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/JobRepositorySupport.java @@ -32,7 +32,7 @@ public class JobRepositorySupport implements JobRepository { /* (non-Javadoc) * @see org.springframework.batch.container.common.repository.JobRepository#findOrCreateJob(org.springframework.batch.container.common.domain.JobConfiguration) */ - public JobInstance findOrCreateJob(JobConfiguration jobConfiguration, JobIdentifier runtimeInformation) { + public JobExecution findOrCreateJob(JobConfiguration jobConfiguration, JobIdentifier runtimeInformation) { return null; } 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 804a9e735..e75732c4a 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 @@ -56,7 +56,7 @@ public class StepExecutorInterruptionTests extends TestCase { private SimpleStepExecutor executor; - public void setUp() { + public void setUp() throws Exception { jobRepository = new SimpleJobRepository(jobDao, stepDao); @@ -65,7 +65,7 @@ public class StepExecutorInterruptionTests extends TestCase { jobConfiguration.addStep(stepConfiguration); JobIdentifier runtimeInformation = new SimpleJobIdentifier("TestJob"); jobConfiguration.setBeanName("testJob"); - job = jobRepository.findOrCreateJob(jobConfiguration, runtimeInformation); + job = jobRepository.findOrCreateJob(jobConfiguration, runtimeInformation).getJob(); executor = new SimpleStepExecutor(); } diff --git a/spring-batch-samples/.settings/hsql-manager.launch b/spring-batch-samples/.settings/hsql-manager.launch index a2b245a33..419b8d151 100644 --- a/spring-batch-samples/.settings/hsql-manager.launch +++ b/spring-batch-samples/.settings/hsql-manager.launch @@ -4,7 +4,7 @@ - + diff --git a/spring-batch-samples/.settings/hsql-server.launch b/spring-batch-samples/.settings/hsql-server.launch index 4e8c704dd..f81667219 100644 --- a/spring-batch-samples/.settings/hsql-server.launch +++ b/spring-batch-samples/.settings/hsql-server.launch @@ -4,7 +4,7 @@ - + diff --git a/spring-batch-samples/.settings/jmxLauncher.launch b/spring-batch-samples/.settings/jmxLauncher.launch new file mode 100644 index 000000000..2d54a277c --- /dev/null +++ b/spring-batch-samples/.settings/jmxLauncher.launch @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/spring-batch-samples/.settings/jobLauncher.launch b/spring-batch-samples/.settings/jobLauncher.launch index 4f5b598f5..9edd2c284 100644 --- a/spring-batch-samples/.settings/jobLauncher.launch +++ b/spring-batch-samples/.settings/jobLauncher.launch @@ -10,6 +10,6 @@ - + diff --git a/spring-batch-samples/src/main/resources/batch.properties b/spring-batch-samples/src/main/resources/batch.properties index d787e6f81..ca92d3c06 100644 --- a/spring-batch-samples/src/main/resources/batch.properties +++ b/spring-batch-samples/src/main/resources/batch.properties @@ -1,9 +1,9 @@ # Placeholders batch.* # for HSQLDB: batch.jdbc.driver=org.hsqldb.jdbcDriver -batch.jdbc.url=jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true +# batch.jdbc.url=jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true # use this one for a separate server process (so you can inspect the results) -# batch.jdbc.url=jdbc:hsqldb:hsql://localhost:9005/samples +batch.jdbc.url=jdbc:hsqldb:hsql://localhost:9005/samples batch.jdbc.user=sa batch.jdbc.password= batch.schema= diff --git a/spring-batch-samples/src/main/resources/business-schema-db2.sql b/spring-batch-samples/src/main/resources/business-schema-db2.sql index 4dfc18a16..9a198dd55 100644 --- a/spring-batch-samples/src/main/resources/business-schema-db2.sql +++ b/spring-batch-samples/src/main/resources/business-schema-db2.sql @@ -33,17 +33,17 @@ INSERT INTO customer (id, version, name, credit) VALUES (2, 0, 'customer2', 1000 INSERT INTO customer (id, version, name, credit) VALUES (3, 0, 'customer3', 100000); INSERT INTO customer (id, version, name, credit) VALUES (4, 0, 'customer4', 100000); - CREATE TABLE PLAYERS ( PLAYER_ID char(8) NOT NULL PRIMARY KEY, LAST_NAME varchar(35) not null, FIRST_NAME varchar(25) not null, POS varchar(10), YEAR_OF_BIRTH BIGINT not null, - YEAR_DRAFTED BIGINT not null); + YEAR_DRAFTED BIGINT not null +); CREATE TABLE GAMES ( - PLAYER_ID char(8) not null PRIMARY KEY, + PLAYER_ID char(8) not null, YEAR BIGINT not null, TEAM char(3) not null, WEEK BIGINT not null, @@ -61,7 +61,7 @@ CREATE TABLE GAMES ( ); CREATE TABLE PLAYER_SUMMARY ( - ID CHAR(8) NOT NULL PRIMARY KEY, + ID CHAR(8) NOT NULL, YEAR BIGINT NOT NULL, COMPLETES BIGINT NOT NULL , ATTEMPTS BIGINT NOT NULL , @@ -72,4 +72,5 @@ CREATE TABLE PLAYER_SUMMARY ( RUSH_YARDS BIGINT NOT NULL , RECEPTIONS BIGINT NOT NULL , RECEPTIONS_YARDS BIGINT NOT NULL , - TOTAL_TD BIGINT NOT NULL ); \ No newline at end of file + TOTAL_TD BIGINT NOT NULL +); \ No newline at end of file diff --git a/spring-batch-samples/src/main/resources/business-schema-derby.sql b/spring-batch-samples/src/main/resources/business-schema-derby.sql index 3edf85929..7aab25bdf 100644 --- a/spring-batch-samples/src/main/resources/business-schema-derby.sql +++ b/spring-batch-samples/src/main/resources/business-schema-derby.sql @@ -33,17 +33,17 @@ INSERT INTO customer (id, version, name, credit) VALUES (2, 0, 'customer2', 1000 INSERT INTO customer (id, version, name, credit) VALUES (3, 0, 'customer3', 100000); INSERT INTO customer (id, version, name, credit) VALUES (4, 0, 'customer4', 100000); - CREATE TABLE PLAYERS ( PLAYER_ID char(8) NOT NULL PRIMARY KEY, LAST_NAME varchar(35) not null, FIRST_NAME varchar(25) not null, POS varchar(10), YEAR_OF_BIRTH BIGINT not null, - YEAR_DRAFTED BIGINT not null); + YEAR_DRAFTED BIGINT not null +); CREATE TABLE GAMES ( - PLAYER_ID char(8) not null PRIMARY KEY, + PLAYER_ID char(8) not null, YEAR BIGINT not null, TEAM char(3) not null, WEEK BIGINT not null, @@ -61,7 +61,7 @@ CREATE TABLE GAMES ( ); CREATE TABLE PLAYER_SUMMARY ( - ID CHAR(8) NOT NULL PRIMARY KEY, + ID CHAR(8) NOT NULL, YEAR BIGINT NOT NULL, COMPLETES BIGINT NOT NULL , ATTEMPTS BIGINT NOT NULL , @@ -72,4 +72,5 @@ CREATE TABLE PLAYER_SUMMARY ( RUSH_YARDS BIGINT NOT NULL , RECEPTIONS BIGINT NOT NULL , RECEPTIONS_YARDS BIGINT NOT NULL , - TOTAL_TD BIGINT NOT NULL ); \ No newline at end of file + TOTAL_TD BIGINT NOT NULL +); \ No newline at end of file diff --git a/spring-batch-samples/src/main/resources/business-schema-hsqldb.sql b/spring-batch-samples/src/main/resources/business-schema-hsqldb.sql index c969380ab..8ce8ab2de 100644 --- a/spring-batch-samples/src/main/resources/business-schema-hsqldb.sql +++ b/spring-batch-samples/src/main/resources/business-schema-hsqldb.sql @@ -37,7 +37,6 @@ INSERT INTO customer (id, version, name, credit) VALUES (2, 0, 'customer2', 1000 INSERT INTO customer (id, version, name, credit) VALUES (3, 0, 'customer3', 100000); INSERT INTO customer (id, version, name, credit) VALUES (4, 0, 'customer4', 100000); - CREATE TABLE PLAYERS ( PLAYER_ID char(8) NOT NULL PRIMARY KEY, LAST_NAME varchar(35) not null, @@ -48,7 +47,7 @@ CREATE TABLE PLAYERS ( ); CREATE TABLE GAMES ( - PLAYER_ID char(8) not null PRIMARY KEY, + PLAYER_ID char(8) not null, YEAR BIGINT not null, TEAM char(3) not null, WEEK BIGINT not null, @@ -66,7 +65,7 @@ CREATE TABLE GAMES ( ); CREATE TABLE PLAYER_SUMMARY ( - ID CHAR(8) NOT NULL PRIMARY KEY, + ID CHAR(8) NOT NULL, YEAR BIGINT NOT NULL, COMPLETES BIGINT NOT NULL , ATTEMPTS BIGINT NOT NULL , diff --git a/spring-batch-samples/src/main/resources/business-schema-oracle10g.sql b/spring-batch-samples/src/main/resources/business-schema-oracle10g.sql index 65a9c89d8..cc991da91 100644 --- a/spring-batch-samples/src/main/resources/business-schema-oracle10g.sql +++ b/spring-batch-samples/src/main/resources/business-schema-oracle10g.sql @@ -33,17 +33,17 @@ INSERT INTO customer (id, version, name, credit) VALUES (2, 0, 'customer2', 1000 INSERT INTO customer (id, version, name, credit) VALUES (3, 0, 'customer3', 100000); INSERT INTO customer (id, version, name, credit) VALUES (4, 0, 'customer4', 100000); - CREATE TABLE PLAYERS ( PLAYER_ID char(8) NOT NULL PRIMARY KEY, LAST_NAME varchar(35) not null, FIRST_NAME varchar(25) not null, POS varchar(10), YEAR_OF_BIRTH NUMBER(38) not null, - YEAR_DRAFTED NUMBER(38) not null); + YEAR_DRAFTED NUMBER(38) not null +); CREATE TABLE GAMES ( - PLAYER_ID char(8) not null PRIMARY KEY, + PLAYER_ID char(8) not null, YEAR NUMBER(38) not null, TEAM char(3) not null, WEEK NUMBER(38) not null, @@ -61,7 +61,7 @@ CREATE TABLE GAMES ( ); CREATE TABLE PLAYER_SUMMARY ( - ID CHAR(8) NOT NULL PRIMARY KEY, + ID CHAR(8) NOT NULL, YEAR NUMBER(38) NOT NULL, COMPLETES NUMBER(38) NOT NULL , ATTEMPTS NUMBER(38) NOT NULL , @@ -72,4 +72,5 @@ CREATE TABLE PLAYER_SUMMARY ( RUSH_YARDS NUMBER(38) NOT NULL , RECEPTIONS NUMBER(38) NOT NULL , RECEPTIONS_YARDS NUMBER(38) NOT NULL , - TOTAL_TD NUMBER(38) NOT NULL ); \ No newline at end of file + TOTAL_TD NUMBER(38) NOT NULL +); \ No newline at end of file diff --git a/spring-batch-samples/src/main/resources/business-schema-postgresql.sql b/spring-batch-samples/src/main/resources/business-schema-postgresql.sql index 4dfc18a16..9a198dd55 100644 --- a/spring-batch-samples/src/main/resources/business-schema-postgresql.sql +++ b/spring-batch-samples/src/main/resources/business-schema-postgresql.sql @@ -33,17 +33,17 @@ INSERT INTO customer (id, version, name, credit) VALUES (2, 0, 'customer2', 1000 INSERT INTO customer (id, version, name, credit) VALUES (3, 0, 'customer3', 100000); INSERT INTO customer (id, version, name, credit) VALUES (4, 0, 'customer4', 100000); - CREATE TABLE PLAYERS ( PLAYER_ID char(8) NOT NULL PRIMARY KEY, LAST_NAME varchar(35) not null, FIRST_NAME varchar(25) not null, POS varchar(10), YEAR_OF_BIRTH BIGINT not null, - YEAR_DRAFTED BIGINT not null); + YEAR_DRAFTED BIGINT not null +); CREATE TABLE GAMES ( - PLAYER_ID char(8) not null PRIMARY KEY, + PLAYER_ID char(8) not null, YEAR BIGINT not null, TEAM char(3) not null, WEEK BIGINT not null, @@ -61,7 +61,7 @@ CREATE TABLE GAMES ( ); CREATE TABLE PLAYER_SUMMARY ( - ID CHAR(8) NOT NULL PRIMARY KEY, + ID CHAR(8) NOT NULL, YEAR BIGINT NOT NULL, COMPLETES BIGINT NOT NULL , ATTEMPTS BIGINT NOT NULL , @@ -72,4 +72,5 @@ CREATE TABLE PLAYER_SUMMARY ( RUSH_YARDS BIGINT NOT NULL , RECEPTIONS BIGINT NOT NULL , RECEPTIONS_YARDS BIGINT NOT NULL , - TOTAL_TD BIGINT NOT NULL ); \ No newline at end of file + TOTAL_TD BIGINT NOT NULL +); \ No newline at end of file diff --git a/spring-batch-samples/src/main/resources/jobs/footballJob.xml b/spring-batch-samples/src/main/resources/jobs/footballJob.xml index b7cf6a711..083a8d308 100644 --- a/spring-batch-samples/src/main/resources/jobs/footballJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/footballJob.xml @@ -114,13 +114,9 @@ - - - - - + class="org.springframework.batch.io.file.support.DefaultFlatFileInputSource" scope="step"> + + @@ -135,13 +131,9 @@ - - - - - + class="org.springframework.batch.io.file.support.DefaultFlatFileInputSource" scope="step"> + + @@ -156,7 +148,8 @@ + class="org.springframework.batch.io.cursor.JdbcCursorInputSource" scope="step"> +