(no commit message)
[utils] / test / enterprise / src / main / java / org / wamblee / test / persistence / JpaBuilder.java
index dbc88dc0ad19e6559ace9ae8b094834fe6710a00..48556cfafcecf1f55690db0ff6b23a000fa788d2 100644 (file)
@@ -29,6 +29,7 @@ import javax.persistence.PersistenceException;
 import org.wamblee.general.ThreadSpecificProxyFactory;
 import org.wamblee.test.jndi.StubInitialContextFactory;
 import org.wamblee.test.transactions.TransactionResource;
+import org.wamblee.test.transactions.TransactionResult;
 
 /**
  * Utility for building an appropriately configured EntityManagerFactory. The
@@ -66,8 +67,8 @@ public class JpaBuilder implements TransactionResource<EntityManager> {
     private String user;
     private String password;
     private EntityManagerFactory factory;
-    private ThreadSpecificProxyFactory<EntityManager> entityManager; 
-    
+    private ThreadSpecificProxyFactory<EntityManager> entityManager;
+
     /**
      * Constructs the builder.
      * 
@@ -86,7 +87,8 @@ public class JpaBuilder implements TransactionResource<EntityManager> {
         url = aUrl;
         user = aUser;
         password = aPassword;
-        entityManager = new ThreadSpecificProxyFactory<EntityManager>(EntityManager.class);
+        entityManager = new ThreadSpecificProxyFactory<EntityManager>(
+            EntityManager.class);
     }
 
     /**
@@ -149,21 +151,47 @@ public class JpaBuilder implements TransactionResource<EntityManager> {
      * passing it the entity manager. Use of this method saves a lot of typing
      * for applications.
      * 
+     * This method requires the transaction to succeed. Otherwise the test will
+     * fail. See {@link #execute(JpaUnitOfWork, TransactionResultCallback)} and
+     * {@link RequireTransactionStatus} for more possibilities.
+     * 
      * @param aWork
      *            Work to execute.
+     * 
      * @return The return value of the execute method of the unit of work.
      */
     public <T> T execute(JpaUnitOfWork<T> aWork) throws Exception {
+        return execute(aWork, new RequireTransactionStatus(
+            TransactionResult.COMMIT));
+    }
+
+    /**
+     * Executes a unit of work. This creates an entitymanager and runs the
+     * {@link JpaUnitOfWork#execute(EntityManager)} within a transaction,
+     * passing it the entity manager. Use of this method saves a lot of typing
+     * for applications.
+     * 
+     * @param aWork
+     *            Work to execute.
+     * @param aTransactionResultCallback
+     *            callback to notify of the result of the transaction.
+     * 
+     * @return The return value of the execute method of the unit of work.
+     */
+    public <T> T execute(JpaUnitOfWork<T> aWork,
+        TransactionResultCallback aCallback) throws Exception {
         EntityManager em = begin();
         try {
             T value = aWork.execute(em);
-            commit(em);
+            TransactionResult result = commit(em);
+            aCallback.status(result);
             return value;
         } catch (Exception e) {
             LOGGER.log(Level.WARNING, "Exception occured", e);
-            rollback(em);
+            TransactionResult result = rollback(em);
+            aCallback.status(result);
             throw e;
-        } 
+        }
     }
 
     @Override
@@ -176,9 +204,18 @@ public class JpaBuilder implements TransactionResource<EntityManager> {
     }
 
     @Override
-    public void commit(EntityManager aEntityManager) {
+    public TransactionResult commit(EntityManager aEntityManager) {
         try {
-            aEntityManager.getTransaction().commit();
+            EntityTransaction transaction = aEntityManager.getTransaction();
+            if (transaction.isActive()) {
+                if (transaction.getRollbackOnly()) {
+                    transaction.rollback();
+                    return TransactionResult.ROLLBACK;
+                }
+                transaction.commit();
+                return TransactionResult.COMMIT;
+            }
+            return TransactionResult.UNKNOWN;
         } finally {
             aEntityManager.close();
             entityManager.set(null);
@@ -186,21 +223,29 @@ public class JpaBuilder implements TransactionResource<EntityManager> {
     }
 
     @Override
-    public void rollback(EntityManager aEntityManager) {
+    public TransactionResult rollback(EntityManager aEntityManager) {
         try {
-            aEntityManager.getTransaction().rollback();
+            EntityTransaction transaction = aEntityManager.getTransaction();
+            if (transaction.isActive()) {
+                transaction.rollback();
+                return TransactionResult.ROLLBACK;
+            }
+            return TransactionResult.UNKNOWN;
         } finally {
-            aEntityManager.close();
+            if (aEntityManager.isOpen()) {
+                aEntityManager.close();
+            }
             entityManager.set(null);
         }
     }
-    
+
     /**
-     * Gets a contextual reference to an entity manager that delegates to the 
-     * appropriate (current) one which is active for the current transaction. 
-     * @return EntityManager. 
+     * Gets a contextual reference to an entity manager that delegates to the
+     * appropriate (current) one which is active for the current transaction.
+     * 
+     * @return EntityManager.
      */
-    public EntityManager getContextualEntityManager() { 
-        return entityManager.getProxy(); 
+    public EntityManager getContextualEntityManager() {
+        return entityManager.getProxy();
     }
 }