diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java index 6330fb532..a8d6aab10 100755 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/item/FaultTolerantChunkProcessor.java @@ -283,8 +283,11 @@ public class FaultTolerantChunkProcessor extends SimpleChunkProcessor extends SimpleChunkProcessor 1 && !rollbackClassifier.classify(e)) { throw new RetryException("Invalid retry state during write caused by " + "exception that does not classify for rollback: ", e); @@ -384,7 +387,7 @@ public class FaultTolerantChunkProcessor extends SimpleChunkProcessor extends SimpleChunkProcessor wrapper : outputs.getSkips()) { - Exception e = wrapper.getException(); + Throwable e = wrapper.getException(); try { getListener().onSkipInWrite(wrapper.getItem(), e); } @@ -464,16 +467,20 @@ public class FaultTolerantChunkProcessor extends SimpleChunkProcessor() { + public void write(List items) throws Exception { + if (items.contains("fail")) { + assertFalse("Expected Error!", true); + } + } + }); + Chunk inputs = new Chunk(Arrays.asList("3", "fail", "2")); + try { + processor.process(contribution, inputs); + fail("Expected Error"); + } + catch (IllegalStateException e) { + assertEquals("Expected Error!", e.getCause().getMessage()); + } + processor.process(contribution, inputs); + try { + processor.process(contribution, inputs); + fail("Expected Error"); + } + catch (IllegalStateException e) { + assertEquals("Expected Error!", e.getCause().getMessage()); + } + assertEquals(1, contribution.getSkipCount()); + assertEquals(1, contribution.getWriteCount()); + } + + @Test + public void testWriteSkipOnException() throws Exception { + processor.setWriteSkipPolicy(new AlwaysSkipItemSkipPolicy()); + processor.setItemWriter(new ItemWriter() { + public void write(List items) throws Exception { + if (items.contains("fail")) { + throw new RuntimeException("Expected Exception!"); + } + } + }); + Chunk inputs = new Chunk(Arrays.asList("3", "fail", "2")); + try { + processor.process(contribution, inputs); + fail("Expected RuntimeException"); + } + catch (RuntimeException e) { + assertEquals("Expected Exception!", e.getMessage()); + } + processor.process(contribution, inputs); + try { + processor.process(contribution, inputs); + fail("Expected RuntimeException"); + } + catch (RuntimeException e) { + assertEquals("Expected Exception!", e.getMessage()); + } + assertEquals(1, contribution.getSkipCount()); + assertEquals(1, contribution.getWriteCount()); + } + @Test public void testTransformWithExceptionAndNoRollback() throws Exception { processor.setItemProcessor(new ItemProcessor() { public String process(String item) throws Exception { - if (item.equals("1")) throw new DataIntegrityViolationException("Planned"); + if (item.equals("1")) + throw new DataIntegrityViolationException("Planned"); return item; } }); processor.setProcessSkipPolicy(new AlwaysSkipItemSkipPolicy()); - processor.setRollbackClassifier(new BinaryExceptionClassifier(Collections.> singleton(DataIntegrityViolationException.class), false)); + processor.setRollbackClassifier(new BinaryExceptionClassifier(Collections + .> singleton(DataIntegrityViolationException.class), false)); Chunk inputs = new Chunk(Arrays.asList("1", "2")); processor.process(contribution, inputs); assertEquals(1, list.size());