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)
This commit is contained in:
dsyer
2007-11-30 13:57:22 +00:00
parent d3b1a7abbe
commit 933b4750aa
2 changed files with 50 additions and 26 deletions

View File

@@ -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();
}
}

View File

@@ -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"));
}
/**