From 3f49e0eb6b4cd4f3e40f2082865c4f8ee4e3288f Mon Sep 17 00:00:00 2001 From: robokaso Date: Thu, 27 Mar 2008 10:01:48 +0000 Subject: [PATCH] RESOLVED - issue BATCH-517: item writers need to handle empty flush gracefully http://jira.springframework.org/browse/BATCH-517 BatchSqlUpdateItemWriter no longer asserts there are items bound to transaction --- .../database/BatchSqlUpdateItemWriter.java | 6 ++-- .../BatchSqlUpdateItemWriterTests.java | 28 +++++++++---------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriter.java b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriter.java index bb5979fd1..33a77916e 100644 --- a/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriter.java +++ b/spring-batch-infrastructure/src/main/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriter.java @@ -17,6 +17,7 @@ package org.springframework.batch.item.database; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; @@ -119,9 +120,10 @@ public class BatchSqlUpdateItemWriter implements ItemWriter, InitializingBean { * @return the processed */ private Set getProcessed() { - Assert.state(TransactionSynchronizationManager.hasResource(ITEMS_PROCESSED), - "Processed items not bound to transaction."); Set processed = (Set) TransactionSynchronizationManager.getResource(ITEMS_PROCESSED); + if (processed == null) { + processed = Collections.EMPTY_SET; + } return processed; } diff --git a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriterTests.java b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriterTests.java index b2dab9597..d28666bee 100644 --- a/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriterTests.java +++ b/spring-batch-infrastructure/src/test/java/org/springframework/batch/item/database/BatchSqlUpdateItemWriterTests.java @@ -47,7 +47,7 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { private JdbcTemplate jdbcTemplate; protected List list = new ArrayList(); - + private RepeatContext context = new RepeatContextSupport(null); private PreparedStatement ps; @@ -149,7 +149,7 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { /** * Test method for * {@link org.springframework.batch.item.database.BatchSqlUpdateItemWriter#flush()}. - * @throws Exception + * @throws Exception */ public void testWriteAndFlush() throws Exception { assertTrue(TransactionSynchronizationManager.hasResource(BatchSqlUpdateItemWriter.ITEMS_PROCESSED)); @@ -159,16 +159,6 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { assertEquals(3, list.size()); assertTrue(list.contains("SQL")); } - - public void testFlushWithFailure() throws Exception{ - tearDown(); - try { - writer.flush(); - fail("Expected IllegalStateException"); - } catch (IllegalStateException e) { - assertTrue("Message should contain hint about transaction: "+e.getMessage(), e.getMessage().indexOf("transaction")>=0); - } - } public void testWriteAndFlushWithFailure() throws Exception { final RuntimeException ex = new RuntimeException("bar"); @@ -180,13 +170,14 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { }); ps.addBatch(); control.setVoidCallable(); - control.expectAndReturn(ps.executeBatch(), new int[] {123}); + control.expectAndReturn(ps.executeBatch(), new int[] { 123 }); control.replay(); writer.write("foo"); try { writer.flush(); fail("Expected RuntimeException"); - } catch (RuntimeException e) { + } + catch (RuntimeException e) { assertEquals("bar", e.getMessage()); } assertFalse(TransactionSynchronizationManager.hasResource(BatchSqlUpdateItemWriter.ITEMS_PROCESSED)); @@ -205,4 +196,13 @@ public class BatchSqlUpdateItemWriterTests extends TestCase { assertTrue(context.isCompleteOnly()); } + /** + * Flushing without writing items previously should be handled gracefully. + */ + public void testEmptyFlush() { + // items are bound on write, so we unbind them first + TransactionSynchronizationManager.unbindResource(BatchSqlUpdateItemWriter.ITEMS_PROCESSED); + writer.flush(); + } + }