(no commit message)
[utils] / test / enterprise / src / main / java / org / wamblee / support / persistence / TransactionProxyFactory.java
index e56d34fa78e7ea94b8c3020a810eb82205d004cb..548a3cdaebc1a8279ebaef779854807387925a99 100644 (file)
@@ -15,6 +15,7 @@
  */
 package org.wamblee.support.persistence;
 
+
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -27,11 +28,25 @@ import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
 
 /**
  * This utility makes sure that each invocation on a certain interface is
- * carried out within a JPA unit of work.
+ * carried out within a JPA unit of work. Note that this is equivalent
+ * to the sementics of a requiresNew transaction attribute. 
  * 
  * Use {@link #getTransactionScopedEntityManager()} to get the transaction
  * scoped entity manager to pass to services.
  * 
+ * 
+ * For example: 
+ * <pre>
+ *     JpaBuilder builder = ...
+ *     TransactionProxyFactory<Service> factory = new TransactionProxyFactory<Service>(
+ *           builder, Service.class);
+ *     Service service = new JpaService(factory.getTransactionScopedEntityManager());
+ *     Service proxy = factory.getProxy(service);
+ *     proxy.executeMethod(...); 
+ * </pre>
+ * The above example executes the executeMethod() call on the service object within an active transaction.
+ * In the constructor of the service a transaction scoped entity manager is passed.  
+ * 
  * @param T
  *            Type of interface to proxy.
  * 
@@ -39,6 +54,13 @@ import org.wamblee.support.persistence.JpaBuilder.JpaUnitOfWork;
  */
 public class TransactionProxyFactory<T> {
 
+    /**
+     * Executes the call on the service within a new transaction.  
+     * 
+     * @author Erik Brakkee
+     *
+     * @param <T> Type of the service interface. 
+     */
     private class UnitOfWorkInvocationHandler<T> implements InvocationHandler {
 
         private T service;
@@ -54,6 +76,7 @@ public class TransactionProxyFactory<T> {
                 .execute(new JpaUnitOfWork<Object>() {
                     @Override
                     public Object execute(EntityManager aEm) throws Exception {
+                        EntityManager oldEm = ENTITY_MANAGER.get(); 
                         try {
                             ENTITY_MANAGER.set(aEm);
                             return aMethod.invoke(service, aArgs);
@@ -67,7 +90,7 @@ public class TransactionProxyFactory<T> {
                             // last resort.
                             throw new RuntimeException(e);
                         } finally {
-                            ENTITY_MANAGER.set(null);
+                            ENTITY_MANAGER.set(oldEm);
                         }
                     }
                 });