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:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user