diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java index 1ef59d9c0..075d91525 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanNonBufferingTests.java @@ -62,7 +62,7 @@ public class FaultTolerantStepFactoryBeanNonBufferingTests { factory.setItemWriter(writer); factory.setSkippableExceptionClasses(skippableExceptions); factory.setSkipLimit(2); - factory.setIsReaderTransactional(true); + factory.setIsReaderTransactionalQueue(true); JobInstance jobInstance = new JobInstance(new Long(1), new JobParameters(), "skipJob"); jobExecution = new JobExecution(jobInstance); diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanTests.java index 77b5ac914..6d37eca06 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/FaultTolerantStepFactoryBeanTests.java @@ -159,7 +159,7 @@ public class FaultTolerantStepFactoryBeanTests { } /** - * Check rollback write exception does not cause rollback when included on + * Check that rollback write exception does cause rollback when included on * transaction attributes as "no rollback for". */ @Test @@ -172,14 +172,15 @@ public class FaultTolerantStepFactoryBeanTests { Step step = (Step) factory.getObject(); StepExecution stepExecution = new StepExecution(step.getName(), jobExecution); + step.execute(stepExecution); - assertEquals(2, stepExecution.getSkipCount()); + assertEquals(1, stepExecution.getSkipCount()); assertEquals(1, stepExecution.getReadSkipCount()); - assertEquals(1, stepExecution.getWriteSkipCount()); + assertEquals(0, stepExecution.getWriteSkipCount()); - // no rollbacks - assertEquals(0, stepExecution.getRollbackCount()); + // one rollback for write exception + assertEquals(1, stepExecution.getRollbackCount()); assertEquals(4, stepExecution.getReadCount()); diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessor.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessor.java new file mode 100644 index 000000000..23fcad4c2 --- /dev/null +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/domain/trade/internal/TradeProcessor.java @@ -0,0 +1,50 @@ +/* + * Copyright 2006-2007 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.batch.sample.domain.trade.internal; + +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.validator.ValidationException; +import org.springframework.batch.sample.domain.trade.Trade; + +/** + * Processes the Trade - throwing validation errors if necessary. + */ +public class TradeProcessor implements ItemProcessor { + + private int failure = -1; + + private int index = 0; + + private Trade failedItem = null; + + /** + * Public setter for the the index on which failure should occur. + * + * @param failure the failure to set + */ + public void setValidationFailure(int failure) { + this.failure = failure; + } + + public Trade process(Trade item) throws Exception { + if ((failedItem == null && index++ == failure) || (failedItem != null && failedItem.equals(item))) { + failedItem = item; + throw new ValidationException("Some bad data for " + failedItem); + } + return item; + } +} diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/support/ItemTrackingItemWriter.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/support/ItemTrackingItemWriter.java index aa468f8d7..e2ff0baed 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/support/ItemTrackingItemWriter.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/support/ItemTrackingItemWriter.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.List; import org.springframework.batch.item.ItemWriter; -import org.springframework.batch.item.validator.ValidationException; /** * Remembers all items written - useful for testing. @@ -21,7 +20,7 @@ public class ItemTrackingItemWriter implements ItemWriter { public void write(List items) throws Exception { if (failed!=null && items.contains(failed)) { - throw new ValidationException("validation failed"); + throw new RuntimeException("write failed again"); } this.items.addAll(items); int current = counter; @@ -29,7 +28,7 @@ public class ItemTrackingItemWriter implements ItemWriter { if (current < failure && counter >= failure) { failed = items.get(failure-current-1); this.items.remove(failed); - throw new ValidationException("validation failed"); + throw new RuntimeException("write failed"); } } @@ -37,7 +36,7 @@ public class ItemTrackingItemWriter implements ItemWriter { return items; } - public void setValidationFailure(int failure) { + public void setWriteFailure(int failure) { this.failure = failure; } diff --git a/spring-batch-samples/src/main/resources/jobs/skipSampleJob.xml b/spring-batch-samples/src/main/resources/jobs/skipSampleJob.xml index 9485aa30c..46ebc1874 100644 --- a/spring-batch-samples/src/main/resources/jobs/skipSampleJob.xml +++ b/spring-batch-samples/src/main/resources/jobs/skipSampleJob.xml @@ -16,20 +16,33 @@ + + + + p:dao-ref="tradeDao" /> - + + + org.springframework.batch.item.validator.ValidationException + + + + + @@ -38,8 +51,7 @@ + class="org.springframework.batch.sample.support.ItemTrackingItemWriter" /> diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/SkipSampleFunctionalTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/SkipSampleFunctionalTests.java index aaeb24acb..2545db4fe 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/SkipSampleFunctionalTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/SkipSampleFunctionalTests.java @@ -45,8 +45,8 @@ public class SkipSampleFunctionalTests extends AbstractValidatingBatchLauncherTe // 5 input records, 1 skipped => 4 written to output assertEquals(before + 4, after); - // no item was processed twice (no rollback occurred despite error on write) - assertEquals(after, writer.getItems().size()); + // no item was processed twice (one rollback occurred due to validation error) + assertEquals(after - 1, writer.getItems().size()); } } diff --git a/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/ItemTrackingItemWriterTests.java b/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/ItemTrackingItemWriterTests.java index 2e66cc197..461379d67 100644 --- a/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/ItemTrackingItemWriterTests.java +++ b/spring-batch-samples/src/test/java/org/springframework/batch/sample/support/ItemTrackingItemWriterTests.java @@ -42,13 +42,13 @@ public class ItemTrackingItemWriterTests { } @Test - public void testValidationFailure() throws Exception { - writer.setValidationFailure(2); + public void testWriteFailure() throws Exception { + writer.setWriteFailure(2); try { writer.write(Arrays.asList("a", "b", "c")); - fail("Expected ValidationException"); + fail("Expected Write Failure Exception"); } - catch (ValidationException e) { + catch (RuntimeException e) { // expected } // the failed item is removed @@ -57,9 +57,9 @@ public class ItemTrackingItemWriterTests { assertEquals(5, writer.getItems().size()); try { writer.write(Arrays.asList("f", "b", "g")); - fail("Expected ValidationException"); + fail("Expected RuntimeException"); } - catch (ValidationException e) { + catch (RuntimeException e) { // expected } // barf immediately if a failure is detected