You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by jl...@apache.org on 2011/07/11 11:14:27 UTC

svn commit: r1145078 - in /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb: core/stateful/StatefulContainer.java persistence/JtaEntityManagerRegistry.java

Author: jlmonteiro
Date: Mon Jul 11 09:14:27 2011
New Revision: 1145078

URL: http://svn.apache.org/viewvc?rev=1145078&view=rev
Log:
OPENEJB-1628 Calling a @Remove method must also close persistence contexts

Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java?rev=1145078&r1=1145077&r2=1145078&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java Mon Jul 11 09:14:27 2011
@@ -427,6 +427,9 @@ public class StatefulContainer implement
             } catch (Throwable e) {
                 handleException(createContext, txPolicy, e);
             } finally {
+                // un register EntityManager
+                unregisterEntityManagers(instance, createContext);
+
                 afterInvoke(createContext, txPolicy, instance);
             }
 
@@ -558,12 +561,27 @@ public class StatefulContainer implement
                         callContext.setCurrentOperation(Operation.REMOVE);
                     }
 
-                    // todo destroy extended persistence contexts
                     discardInstance(callContext);
                 }
 
+                // un register EntityManager
+                Map<EntityManagerFactory, EntityManager> unregisteredEntityManagers = unregisterEntityManagers(instance, callContext);
+
                 // Commit transaction
                 afterInvoke(callContext, txPolicy, instance);
+
+                // Un register and close extended persistence contexts
+                /*
+                7.6.2 Container-managed Extended Persistence Context
+                A container-managed extended persistence context can only be initiated within the scope of a stateful
+                session bean. It exists from the point at which the stateful session bean that declares a dependency on an
+                entity manager of type PersistenceContextType.EXTENDED is created, and is said to be bound
+                to the stateful session bean. The dependency on the extended persistence context is declared by means
+                of the PersistenceContext annotation or persistence-context-ref deployment descriptor element.
+                The persistence context is closed by the container when the @Remove method of the stateful session
+                bean completes (or the stateful session bean instance is otherwise destroyed).
+                */
+                closeEntityManagers(unregisteredEntityManagers);
             }
 
             return returnValue;
@@ -600,6 +618,7 @@ public class StatefulContainer implement
 
                 // Register the entity managers
                 registerEntityManagers(instance, callContext);
+
                 // Register for synchronization callbacks
                 registerSessionSynchronization(instance, callContext);
 
@@ -619,6 +638,9 @@ public class StatefulContainer implement
             } catch (Throwable e) {
                 handleException(callContext, txPolicy, e);
             } finally {
+                // un register EntityManager
+                unregisterEntityManagers(instance, callContext);
+
                 // Commit transaction
                 afterInvoke(callContext, txPolicy, instance);
             }
@@ -777,7 +799,6 @@ public class StatefulContainer implement
 
     private void afterInvoke(ThreadContext callContext, TransactionPolicy txPolicy, Instance instance) throws OpenEJBException {
         try {
-            unregisterEntityManagers(instance, callContext);
             if (instance != null && txPolicy instanceof BeanTransactionPolicy) {
                 // suspend the currently running transaction if any
                 SuspendedTransaction suspendedTransaction = null;
@@ -847,16 +868,24 @@ public class StatefulContainer implement
         }
     }
 
-    private void unregisterEntityManagers(Instance instance, ThreadContext callContext) {
-        if (entityManagerRegistry == null) return;
-        if (instance == null) return;
+    private Map<EntityManagerFactory, EntityManager> unregisterEntityManagers(Instance instance, ThreadContext callContext) {
+        if (entityManagerRegistry == null) return null;
+        if (instance == null) return null;
 
         BeanContext beanContext = callContext.getBeanContext();
 
         // register them
-        entityManagerRegistry.removeEntityManagers((String) beanContext.getDeploymentID(), instance.primaryKey);
+        return entityManagerRegistry.removeEntityManagers((String) beanContext.getDeploymentID(), instance.primaryKey);
     }
 
+    private void closeEntityManagers(Map<EntityManagerFactory, EntityManager> unregisteredEntityManagers) {
+        if (unregisteredEntityManagers == null) return;
+
+        // iterate throughout all EM to close the surrounding EntityManager
+        for (EntityManager entityManager : unregisteredEntityManagers.values()) {
+            ((EntityManager) entityManager.getDelegate()).close();
+        }
+    }
 
     private void registerSessionSynchronization(Instance instance, ThreadContext callContext)  {
         TransactionPolicy txPolicy = callContext.getTransactionPolicy();

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java?rev=1145078&r1=1145077&r2=1145078&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManagerRegistry.java Mon Jul 11 09:14:27 2011
@@ -144,9 +144,10 @@ public class JtaEntityManagerRegistry {
     /**
      * Removed the registered entity managers for the specified component.
      * @param deploymentId the id of the component
+     * @return EntityManager map we are removing
      */
-    public void removeEntityManagers(String deploymentId, Object primaryKey) {
-        extendedRegistry.get().removeEntityManagers(new InstanceId(deploymentId, primaryKey));
+    public Map<EntityManagerFactory, EntityManager> removeEntityManagers(String deploymentId, Object primaryKey) {
+        return extendedRegistry.get().removeEntityManagers(new InstanceId(deploymentId, primaryKey));
     }
 
     /**
@@ -210,12 +211,12 @@ public class JtaEntityManagerRegistry {
             entityManagersByDeploymentId.put(instanceId, entityManagers);
         }
 
-        private void removeEntityManagers(InstanceId instanceId) {
+        private Map<EntityManagerFactory, EntityManager> removeEntityManagers(InstanceId instanceId) {
             if (instanceId == null) {
                 throw new NullPointerException("InstanceId is null");
             }
 
-            entityManagersByDeploymentId.remove(instanceId);
+            return entityManagersByDeploymentId.remove(instanceId);
         }
 
         private EntityManager getInheritedEntityManager(EntityManagerFactory entityManagerFactory) {