added "flush()" method to TransactionStatus and TransactionSynchronization interfaces; test context manager automatically flushes transactions before rolling back; general polishing of transaction management code

This commit is contained in:
Juergen Hoeller
2009-02-19 00:24:05 +00:00
parent dd7d299aa4
commit 4cc42bf16f
34 changed files with 415 additions and 134 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.orm.hibernate3;
import java.util.ArrayList;
import java.util.List;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
@@ -108,7 +107,7 @@ public class HibernateJtaTransactionTests extends TestCase {
session.createQuery("some query string");
sessionControl.setReturnValue(query, 1);
if (readOnly) {
session.setFlushMode(FlushMode.NEVER);
session.setFlushMode(FlushMode.MANUAL);
sessionControl.setVoidCallable(1);
}
query.list();
@@ -370,6 +369,14 @@ public class HibernateJtaTransactionTests extends TestCase {
}
public void testJtaTransactionRollback() throws Exception {
doTestJtaTransactionRollback(false);
}
public void testJtaTransactionRollbackWithFlush() throws Exception {
doTestJtaTransactionRollback(true);
}
private void doTestJtaTransactionRollback(final boolean flush) throws Exception {
MockControl utControl = MockControl.createControl(UserTransaction.class);
UserTransaction ut = (UserTransaction) utControl.getMock();
ut.getStatus();
@@ -390,6 +397,10 @@ public class HibernateJtaTransactionTests extends TestCase {
sfControl.setReturnValue(session, 1);
session.getSessionFactory();
sessionControl.setReturnValue(sf, 1);
if (flush) {
session.flush();
sessionControl.setVoidCallable(1);
}
sfControl.replay();
sessionControl.replay();
@@ -409,6 +420,9 @@ public class HibernateJtaTransactionTests extends TestCase {
return l;
}
});
if (flush) {
status.flush();
}
status.setRollbackOnly();
sessionControl.verify();
sessionControl.reset();
@@ -495,7 +509,7 @@ public class HibernateJtaTransactionTests extends TestCase {
sessionControl.setReturnValue(true, 5);
session.getFlushMode();
if (flushNever) {
sessionControl.setReturnValue(FlushMode.NEVER, 1);
sessionControl.setReturnValue(FlushMode.MANUAL, 1);
if (!readOnly) {
session.setFlushMode(FlushMode.AUTO);
sessionControl.setVoidCallable(1);
@@ -546,7 +560,7 @@ public class HibernateJtaTransactionTests extends TestCase {
session.flush();
sessionControl.setVoidCallable(1);
if (flushNever) {
session.setFlushMode(FlushMode.NEVER);
session.setFlushMode(FlushMode.MANUAL);
sessionControl.setVoidCallable(1);
}
}
@@ -1064,15 +1078,15 @@ public class HibernateJtaTransactionTests extends TestCase {
session.getSessionFactory();
sessionControl.setReturnValue(sf, 1);
session.getFlushMode();
sessionControl.setReturnValue(FlushMode.NEVER, 1);
sessionControl.setReturnValue(FlushMode.MANUAL, 1);
session.setFlushMode(FlushMode.AUTO);
sessionControl.setVoidCallable(1);
session.flush();
sessionControl.setVoidCallable(1);
session.setFlushMode(FlushMode.NEVER);
session.setFlushMode(FlushMode.MANUAL);
sessionControl.setVoidCallable(1);
session.getFlushMode();
sessionControl.setReturnValue(FlushMode.NEVER, 1);
sessionControl.setReturnValue(FlushMode.MANUAL, 1);
session.close();
sessionControl.setReturnValue(null, 1);
sfControl.replay();
@@ -1306,7 +1320,7 @@ public class HibernateJtaTransactionTests extends TestCase {
sfControl.setReturnValue(tm, 7);
session.isOpen();
sessionControl.setReturnValue(true, 8);
session.setFlushMode(FlushMode.NEVER);
session.setFlushMode(FlushMode.MANUAL);
sessionControl.setVoidCallable(1);
session.close();
sessionControl.setReturnValue(null, 2);
@@ -1667,7 +1681,7 @@ public class HibernateJtaTransactionTests extends TestCase {
sessionControl.setReturnValue(true, 5);
session.getFlushMode();
if (flushNever) {
sessionControl.setReturnValue(FlushMode.NEVER, 1);
sessionControl.setReturnValue(FlushMode.MANUAL, 1);
session.setFlushMode(FlushMode.AUTO);
sessionControl.setVoidCallable(1);
}
@@ -1702,7 +1716,7 @@ public class HibernateJtaTransactionTests extends TestCase {
session.flush();
sessionControl.setVoidCallable(1);
if (flushNever) {
session.setFlushMode(FlushMode.NEVER);
session.setFlushMode(FlushMode.MANUAL);
sessionControl.setVoidCallable(1);
}
session.disconnect();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1779,6 +1779,51 @@ public class HibernateTransactionManagerTests extends TestCase {
assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
}
public void testTransactionFlush() throws Exception {
MockControl sfControl = MockControl.createControl(SessionFactory.class);
final SessionFactory sf = (SessionFactory) sfControl.getMock();
MockControl sessionControl = MockControl.createControl(Session.class);
final Session session = (Session) sessionControl.getMock();
MockControl txControl = MockControl.createControl(Transaction.class);
Transaction tx = (Transaction) txControl.getMock();
sf.openSession();
sfControl.setReturnValue(session, 1);
session.beginTransaction();
sessionControl.setReturnValue(tx, 1);
session.flush();
sessionControl.setVoidCallable(1);
tx.commit();
txControl.setVoidCallable(1);
session.close();
sessionControl.setReturnValue(null, 1);
sfControl.replay();
sessionControl.replay();
txControl.replay();
HibernateTransactionManager tm = new HibernateTransactionManager(sf);
tm.setPrepareConnection(false);
TransactionTemplate tt = new TransactionTemplate(tm);
assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
tt.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread session", TransactionSynchronizationManager.hasResource(sf));
assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly());
assertTrue(TransactionSynchronizationManager.isActualTransactionActive());
status.flush();
}
});
assertTrue("Hasn't thread session", !TransactionSynchronizationManager.hasResource(sf));
assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
sfControl.verify();
sessionControl.verify();
txControl.verify();
}
protected void tearDown() {
assertTrue(TransactionSynchronizationManager.getResourceMap().isEmpty());
assertFalse(TransactionSynchronizationManager.isSynchronizationActive());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2007 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1222,4 +1222,41 @@ public class JdoTransactionManagerTests extends TestCase {
queryControl.verify();
}
public void testTransactionFlush() {
pmf.getConnectionFactory();
pmfControl.setReturnValue(null, 1);
pmf.getPersistenceManager();
pmfControl.setReturnValue(pm, 1);
pm.currentTransaction();
pmControl.setReturnValue(tx, 3);
pm.flush();
pmControl.setVoidCallable(1);
pm.close();
pmControl.setVoidCallable(1);
tx.begin();
txControl.setVoidCallable(1);
tx.getRollbackOnly();
txControl.setReturnValue(false, 1);
tx.commit();
txControl.setVoidCallable(1);
pmfControl.replay();
pmControl.replay();
txControl.replay();
PlatformTransactionManager tm = new JdoTransactionManager(pmf);
TransactionTemplate tt = new TransactionTemplate(tm);
assertTrue("Hasn't thread pm", !TransactionSynchronizationManager.hasResource(pmf));
assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
tt.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue("Has thread pm", TransactionSynchronizationManager.hasResource(pmf));
status.flush();
}
});
assertTrue("Hasn't thread pm", !TransactionSynchronizationManager.hasResource(pmf));
assertTrue("JTA synchronizations not active", !TransactionSynchronizationManager.isSynchronizationActive());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.orm.jpa;
import java.lang.reflect.Proxy;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.FlushModeType;
@@ -95,9 +94,8 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
Person notThere = sharedEntityManager.getReference(Person.class, 666);
// We may get here (as with Hibernate).
// Either behaviour is
// valid--throw exception on first access
// or on getReference itself
// Either behaviour is valid: throw exception on first access
// or on getReference itself.
notThere.getFirstName();
}
@@ -175,8 +173,7 @@ public abstract class AbstractContainerEntityManagerFactoryIntegrationTests
}
protected void testInstantiateAndSave(EntityManager em) {
assertEquals("Should be no people from previous transactions",
0, countRowsInTable("person"));
assertEquals("Should be no people from previous transactions", 0, countRowsInTable("person"));
Person p = new Person();
p.setFirstName("Tony");
p.setLastName("Blair");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2006 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -93,13 +93,11 @@ public class ApplicationManagedEntityManagerIntegrationTests extends AbstractEnt
em.persist(p);
em.flush();
assertEquals("1 row must have been inserted",
1, countRowsInTable("person"));
assertEquals("1 row must have been inserted", 1, countRowsInTable("person"));
}
public void testStateClean() {
assertEquals("Should be no people from previous transactions",
0, countRowsInTable("person"));
assertEquals("Should be no people from previous transactions", 0, countRowsInTable("person"));
}
public void testReuseInNewTransaction() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2006 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -114,8 +114,7 @@ public class ContainerManagedEntityManagerIntegrationTests extends AbstractEntit
em.persist(p);
em.flush();
assertEquals("1 row must have been inserted",
1, countRowsInTable("person"));
assertEquals("1 row must have been inserted", 1, countRowsInTable("person"));
}
public void testReuseInNewTransaction() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 the original author or authors.
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1071,4 +1071,33 @@ public class JpaTransactionManagerTests extends TestCase {
txControl.verify();
}
public void testTransactionFlush() {
managerControl.expectAndReturn(manager.getTransaction(), tx);
txControl.expectAndReturn(tx.getRollbackOnly(), false);
managerControl.expectAndReturn(manager.getTransaction(), tx);
tx.commit();
manager.flush();
factoryControl.replay();
managerControl.replay();
txControl.replay();
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
tt.execute(new TransactionCallbackWithoutResult() {
public void doInTransactionWithoutResult(TransactionStatus status) {
assertTrue(TransactionSynchronizationManager.hasResource(factory));
status.flush();
}
});
assertTrue(!TransactionSynchronizationManager.hasResource(factory));
assertTrue(!TransactionSynchronizationManager.isSynchronizationActive());
factoryControl.verify();
managerControl.verify();
txControl.verify();
}
}