From 933b4750aa3e66111a7b9482878a23391b4e476a Mon Sep 17 00:00:00 2001 From: dsyer Date: Fri, 30 Nov 2007 13:57:22 +0000 Subject: [PATCH] CLOSED - issue BATCH-237: HibernateAwareItemWriter should clear session after flushing http://opensource.atlassian.com/projects/spring/browse/BATCH-237 Added clear() after flush (and test case) --- .../io/support/HibernateAwareItemWriter.java | 49 +++++++++++++------ .../HibernateAwareItemWriterTests.java | 27 ++++++---- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/infrastructure/src/main/java/org/springframework/batch/io/support/HibernateAwareItemWriter.java b/infrastructure/src/main/java/org/springframework/batch/io/support/HibernateAwareItemWriter.java index 92b85a17d..0740568e6 100644 --- a/infrastructure/src/main/java/org/springframework/batch/io/support/HibernateAwareItemWriter.java +++ b/infrastructure/src/main/java/org/springframework/batch/io/support/HibernateAwareItemWriter.java @@ -44,23 +44,27 @@ import org.springframework.util.Assert; * @author Dave Syer * */ -public class HibernateAwareItemWriter implements - ItemWriter, RepeatInterceptor, InitializingBean { +public class HibernateAwareItemWriter implements ItemWriter, RepeatInterceptor, + InitializingBean { /** * Key for items processed in the current transaction {@link RepeatContext}. */ - private static final String ITEMS_PROCESSED = HibernateAwareItemWriter.class.getName()+".ITEMS_PROCESSED"; + private static final String ITEMS_PROCESSED = HibernateAwareItemWriter.class + .getName() + + ".ITEMS_PROCESSED"; /** * Key for {@link RepeatContext} in transaction resource context. */ - private static final String WRITER_REPEAT_CONTEXT = HibernateAwareItemWriter.class.getName()+".WRITER_REPEAT_CONTEXT"; + private static final String WRITER_REPEAT_CONTEXT = HibernateAwareItemWriter.class + .getName() + + ".WRITER_REPEAT_CONTEXT"; private Set failed = new HashSet(); private ItemWriter delegate; - + private HibernateOperations hibernateTemplate; /** @@ -72,23 +76,26 @@ public class HibernateAwareItemWriter implements public void setDelegate(ItemWriter delegate) { this.delegate = delegate; } - + /** * Public setter for the {@link HibernateOperations} property. - * - * @param hibernateTemplate the hibernateTemplate to set + * + * @param hibernateTemplate + * the hibernateTemplate to set */ public void setHibernateTemplate(HibernateOperations hibernateTemplate) { this.hibernateTemplate = hibernateTemplate; } - + /** - * Set the Hibernate SessionFactory to be used internally. - * Will automatically create a HibernateTemplate for the given SessionFactory. + * Set the Hibernate SessionFactory to be used internally. Will + * automatically create a HibernateTemplate for the given SessionFactory. + * * @see #setHibernateTemplate */ public final void setSessionFactory(SessionFactory sessionFactory) { - this.hibernateTemplate = new HibernateTemplate(sessionFactory);; + this.hibernateTemplate = new HibernateTemplate(sessionFactory); + ; } /** @@ -100,8 +107,8 @@ public class HibernateAwareItemWriter implements Assert .notNull(delegate, "HibernateAwareItemWriter requires an ItemWriter as a delegate."); - Assert - .notNull(hibernateTemplate, "HibernateAwareItemWriter requires a HibernateOperations"); + Assert.notNull(hibernateTemplate, + "HibernateAwareItemWriter requires a HibernateOperations"); } /** @@ -157,7 +164,7 @@ public class HibernateAwareItemWriter implements RepeatInterceptor interceptor = (RepeatInterceptor) delegate; interceptor.close(context); } - hibernateTemplate.flush(); + flush(); } catch (RuntimeException e) { synchronized (failed) { failed.addAll(getProcessed()); @@ -170,6 +177,16 @@ public class HibernateAwareItemWriter implements unsetContext(); } + /** + * Wrapper for Hibernate flush. + */ + private void flush() { + hibernateTemplate.flush(); + // This should happen when the transaction commits anyway, but to be + // sure... + hibernateTemplate.clear(); + } + /** * Does nothing unless the delegate is also a {@link RepeatInterceptor} in * which case pass on the call to him. @@ -264,7 +281,7 @@ public class HibernateAwareItemWriter implements context.setCompleteOnly(); // Flush now, so that if there is a failure this record can be // skipped. - hibernateTemplate.flush(); + flush(); } } diff --git a/infrastructure/src/test/java/org/springframework/batch/io/support/HibernateAwareItemWriterTests.java b/infrastructure/src/test/java/org/springframework/batch/io/support/HibernateAwareItemWriterTests.java index 58fdeff7b..f4540d167 100644 --- a/infrastructure/src/test/java/org/springframework/batch/io/support/HibernateAwareItemWriterTests.java +++ b/infrastructure/src/test/java/org/springframework/batch/io/support/HibernateAwareItemWriterTests.java @@ -37,6 +37,15 @@ import org.springframework.transaction.support.TransactionSynchronizationManager */ public class HibernateAwareItemWriterTests extends TestCase { + private class HibernateTemplateWrapper extends HibernateTemplate { + public void flush() throws DataAccessException { + list.add("flush"); + } + public void clear() { + list.add("clear"); + }; + } + private class StubItemWriter implements ItemWriter, RepeatInterceptor { public void write(Object item) { list.add(item); @@ -78,11 +87,7 @@ public class HibernateAwareItemWriterTests extends TestCase { writer.setDelegate(new StubItemWriter()); context = new RepeatContextSupport(null); writer.open(context); - writer.setHibernateTemplate(new HibernateTemplate() { - public void flush() throws DataAccessException { - list.add("flush"); - } - }); + writer.setHibernateTemplate(new HibernateTemplateWrapper()); list.clear(); } @@ -163,7 +168,7 @@ public class HibernateAwareItemWriterTests extends TestCase { */ public void testWriteAndCloseWithFailure() { final RuntimeException ex = new RuntimeException("bar"); - writer.setHibernateTemplate(new HibernateTemplate() { + writer.setHibernateTemplate(new HibernateTemplateWrapper() { public void flush() throws DataAccessException { throw ex; } @@ -178,14 +183,15 @@ public class HibernateAwareItemWriterTests extends TestCase { assertEquals(3, list.size()); assertTrue(list.contains(ex)); assertTrue(list.contains(context)); - writer.setHibernateTemplate(new HibernateTemplate() { + writer.setHibernateTemplate(new HibernateTemplateWrapper() { public void flush() throws DataAccessException { list.add("flush"); } }); writer.write("foo"); - assertEquals(5, list.size()); + assertEquals(6, list.size()); assertTrue(list.contains("flush")); + assertTrue(list.contains("clear")); } /** @@ -212,7 +218,7 @@ public class HibernateAwareItemWriterTests extends TestCase { */ public void testClose() { writer.close(context); - assertEquals(2, list.size()); + assertEquals(3, list.size()); assertTrue(list.contains("flush")); } @@ -225,8 +231,9 @@ public class HibernateAwareItemWriterTests extends TestCase { String key = (String) map.keySet().iterator().next(); TransactionSynchronizationManager.unbindResource(key); writer.close(context); - assertEquals(2, list.size()); + assertEquals(3, list.size()); assertTrue(list.contains("flush")); + assertTrue(list.contains("clear")); } /**