Author: jlmonteiro
Date: Tue Jul 12 10:01:47 2011
New Revision: 1145516
URL: http://svn.apache.org/viewvc?rev=1145516&view=rev
Log:
OPENEJB-1628 Calling a @Remove method must also close persistence contexts
Second try dealing with Inherited Extended Persistence Contexts
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java
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
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/EntityManagerPropogationTest.java
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java?rev=1145516&r1=1145515&r2=1145516&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java
Tue Jul 12 10:01:47 2011
@@ -17,24 +17,25 @@
*/
package org.apache.openejb.core.managed;
-import java.io.Serializable;
-import java.io.ObjectStreamException;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Stack;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.EntityManager;
-import javax.transaction.Transaction;
-
import org.apache.openejb.BeanContext;
import
org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.persistence.JtaEntityManagerRegistry;
import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.util.Duration;
import org.apache.openejb.util.Index;
import org.apache.openejb.util.PojoSerialization;
+import javax.persistence.EntityManagerFactory;
+import javax.transaction.Transaction;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
public class Instance implements Serializable {
private static final long serialVersionUID = 2862563626506556542L;
public final BeanContext beanContext;
@@ -45,15 +46,15 @@ public class Instance implements Seriali
private boolean inUse;
private SuspendedTransaction beanTransaction;
private Stack<Transaction> transaction = new Stack<Transaction>();
- private final Lock lock = new ReentrantLock();
+ private final ReentrantLock lock = new ReentrantLock();
// todo if we keyed by an entity manager factory id we would not have to
make this transient and rebuild the index below
// This would require that we crete an id and that we track it
// alternatively, we could use ImmutableArtifact with some read/write
replace magic
- private Map<EntityManagerFactory, EntityManager> entityManagers;
- private final EntityManager[] entityManagerArray;
+ private Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers;
+ private final JtaEntityManagerRegistry.EntityManagerTracker[]
entityManagerArray;
- public Instance(BeanContext beanContext, Object primaryKey, Object bean,
Map<String, Object> interceptors, Map<EntityManagerFactory, EntityManager>
entityManagers) {
+ public Instance(BeanContext beanContext, Object primaryKey, Object bean,
Map<String, Object> interceptors, Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers) {
this.beanContext = beanContext;
this.primaryKey = primaryKey;
this.bean = bean;
@@ -62,7 +63,7 @@ public class Instance implements Seriali
this.entityManagerArray = null;
}
- public Instance(Object deploymentId, Object primaryKey, Object bean,
Map<String, Object> interceptors, EntityManager[] entityManagerArray) {
+ public Instance(Object deploymentId, Object primaryKey, Object bean,
Map<String, Object> interceptors,
JtaEntityManagerRegistry.EntityManagerTracker[] entityManagerArray) {
this.beanContext =
SystemInstance.get().getComponent(ContainerSystem.class).getBeanContext(deploymentId);
if (beanContext == null) {
throw new IllegalArgumentException("Unknown deployment " +
deploymentId);
@@ -73,6 +74,10 @@ public class Instance implements Seriali
this.entityManagerArray = entityManagerArray;
}
+ public Duration getTimeOut() {
+ return beanContext.getStatefulTimeout();
+ }
+
public synchronized boolean isInUse() {
return inUse;
}
@@ -107,15 +112,20 @@ public class Instance implements Seriali
} else if (transaction != null){
this.transaction.push(transaction);
}
+ }
+ public synchronized void releaseLock() {
+ if (lock.isHeldByCurrentThread()) {
+ lock.unlock();
+ }
}
- public synchronized Map<EntityManagerFactory, EntityManager>
getEntityManagers(Index<EntityManagerFactory, Map> factories) {
+ public synchronized Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker>
getEntityManagers(Index<EntityManagerFactory, Map> factories) {
if (entityManagers == null && entityManagerArray != null) {
- entityManagers = new HashMap<EntityManagerFactory,
EntityManager>();
+ entityManagers = new HashMap<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker>();
for (int i = 0; i < entityManagerArray.length; i++) {
EntityManagerFactory entityManagerFactory =
factories.getKey(i);
- EntityManager entityManager = entityManagerArray[i];
+ JtaEntityManagerRegistry.EntityManagerTracker entityManager =
entityManagerArray[i];
entityManagers.put(entityManagerFactory, entityManager);
}
}
@@ -138,36 +148,40 @@ public class Instance implements Seriali
public final Object primaryKey;
public final Object bean;
public final Map<String, Object> interceptors;
- public final EntityManager[] entityManagerArray;
+ public final JtaEntityManagerRegistry.EntityManagerTracker[]
entityManagerArray;
public Serialization(Instance i) {
deploymentId = i.beanContext.getDeploymentID();
primaryKey = i.primaryKey;
- if (i.bean instanceof Serializable) {
- bean = i.bean;
- } else {
- bean = new PojoSerialization(i.bean);
- }
+ bean = toSerializable(i.bean);
- interceptors = new HashMap(i.interceptors.size());
+ interceptors = new HashMap<String, Object>(i.interceptors.size());
for (Map.Entry<String, Object> e : i.interceptors.entrySet()) {
if (e.getValue() == i.bean) {
// need to use the same wrapped reference or well get two
copies.
interceptors.put(e.getKey(), bean);
- } else if (!(e.getValue() instanceof Serializable)) {
- interceptors.put(e.getKey(), new
PojoSerialization(e.getValue()));
+ } else {
+ interceptors.put(e.getKey(), toSerializable(e.getValue()));
}
}
if (i.entityManagerArray != null) {
entityManagerArray = i.entityManagerArray;
} else if (i.entityManagers != null) {
- entityManagerArray = i.entityManagers.values().toArray(new
EntityManager[i.entityManagers.values().size()]);
+ entityManagerArray = i.entityManagers.values().toArray(new
JtaEntityManagerRegistry.EntityManagerTracker[i.entityManagers.values().size()]);
} else {
entityManagerArray = null;
}
}
+ private static Object toSerializable(Object obj) {
+ if (obj instanceof Serializable) {
+ return obj;
+ } else {
+ return new PojoSerialization(obj);
+ }
+ }
+
protected Object readResolve() throws ObjectStreamException {
// Anything wrapped with PojoSerialization will have been
automatically
// unwrapped via it's own readResolve so passing in the raw bean
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java?rev=1145516&r1=1145515&r2=1145516&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java
Tue Jul 12 10:01:47 2011
@@ -16,32 +16,6 @@
*/
package org.apache.openejb.core.managed;
-import java.lang.reflect.Method;
-import java.lang.management.ManagementFactory;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.rmi.dgc.VMID;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import javax.ejb.EJBAccessException;
-import javax.ejb.EJBContext;
-import javax.ejb.EJBException;
-import javax.ejb.EJBHome;
-import javax.ejb.EJBLocalHome;
-import javax.ejb.RemoveException;
-import javax.ejb.SessionBean;
-import javax.ejb.SessionContext;
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.transaction.Transaction;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
import org.apache.openejb.ApplicationException;
import org.apache.openejb.BeanContext;
import org.apache.openejb.ContainerType;
@@ -51,15 +25,10 @@ import org.apache.openejb.OpenEJBExcepti
import org.apache.openejb.ProxyInfo;
import org.apache.openejb.RpcContainer;
import org.apache.openejb.SystemException;
-import org.apache.openejb.monitoring.StatsInterceptor;
-import org.apache.openejb.monitoring.ObjectNameBuilder;
-import org.apache.openejb.monitoring.ManagedMBean;
import org.apache.openejb.core.ExceptionType;
-import static org.apache.openejb.core.ExceptionType.APPLICATION_ROLLBACK;
-import static org.apache.openejb.core.ExceptionType.SYSTEM;
+import org.apache.openejb.core.InstanceContext;
import org.apache.openejb.core.Operation;
import org.apache.openejb.core.ThreadContext;
-import org.apache.openejb.core.InstanceContext;
import org.apache.openejb.core.interceptor.InterceptorData;
import org.apache.openejb.core.interceptor.InterceptorStack;
import org.apache.openejb.core.managed.Cache.CacheFilter;
@@ -67,21 +36,53 @@ import org.apache.openejb.core.managed.C
import org.apache.openejb.core.transaction.BeanTransactionPolicy;
import
org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction;
import org.apache.openejb.core.transaction.EjbTransactionUtil;
-import static
org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy;
-import static
org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException;
-import static
org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException;
import org.apache.openejb.core.transaction.EjbUserTransaction;
-import org.apache.openejb.core.transaction.TransactionPolicy;
import org.apache.openejb.core.transaction.JtaTransactionPolicy;
+import org.apache.openejb.core.transaction.TransactionPolicy;
import
org.apache.openejb.core.transaction.TransactionPolicy.TransactionSynchronization;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.monitoring.ManagedMBean;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.monitoring.StatsInterceptor;
import org.apache.openejb.persistence.EntityManagerAlreadyRegisteredException;
import org.apache.openejb.persistence.JtaEntityManagerRegistry;
import org.apache.openejb.spi.SecurityService;
+import org.apache.openejb.util.Duration;
import org.apache.openejb.util.Index;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.Duration;
+
+import javax.ejb.EJBAccessException;
+import javax.ejb.EJBContext;
+import javax.ejb.EJBException;
+import javax.ejb.EJBHome;
+import javax.ejb.EJBLocalHome;
+import javax.ejb.RemoveException;
+import javax.ejb.SessionBean;
+import javax.ejb.SessionContext;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.transaction.Transaction;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.rmi.NoSuchObjectException;
+import java.rmi.RemoteException;
+import java.rmi.dgc.VMID;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.apache.openejb.core.ExceptionType.APPLICATION_ROLLBACK;
+import static org.apache.openejb.core.ExceptionType.SYSTEM;
+import static
org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy;
+import static
org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException;
+import static
org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException;
public class ManagedContainer implements RpcContainer {
private static final Logger logger =
Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
@@ -343,7 +344,7 @@ public class ManagedContainer implements
checkAuthorization(callMethod, interfaceType);
// Create the extended entity managers for this instance
- Index<EntityManagerFactory, EntityManager> entityManagers =
createEntityManagers(beanContext);
+ Index<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers =
createEntityManagers(beanContext);
// Register the newly created entity managers
if (entityManagers != null) {
@@ -738,29 +739,33 @@ public class ManagedContainer implements
}
}
- private Index<EntityManagerFactory, EntityManager>
createEntityManagers(BeanContext beanContext) {
+ private Index<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> createEntityManagers(BeanContext
beanContext) {
// create the extended entity managers
Index<EntityManagerFactory, Map> factories =
beanContext.getExtendedEntityManagerFactories();
- Index<EntityManagerFactory, EntityManager> entityManagers = null;
+ Index<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers = null;
if (factories != null && factories.size() > 0) {
- entityManagers = new Index<EntityManagerFactory,
EntityManager>(new ArrayList<EntityManagerFactory>(factories.keySet()));
+ entityManagers = new Index<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker>(new
ArrayList<EntityManagerFactory>(factories.keySet()));
for (Map.Entry<EntityManagerFactory, Map> entry :
factories.entrySet()) {
EntityManagerFactory entityManagerFactory = entry.getKey();
Map properties = entry.getValue();
- EntityManager entityManager =
entityManagerRegistry.getInheritedEntityManager(entityManagerFactory);
- if (entityManager == null) {
+ JtaEntityManagerRegistry.EntityManagerTracker
entityManagerTracker =
entityManagerRegistry.getInheritedEntityManager(entityManagerFactory);
+ EntityManager entityManager;
+ if (entityManagerTracker == null) {
if (properties != null) {
entityManager =
entityManagerFactory.createEntityManager(properties);
} else {
entityManager =
entityManagerFactory.createEntityManager();
}
+ entityManagerTracker = new
JtaEntityManagerRegistry.EntityManagerTracker(entityManager);
+ } else {
+ entityManagerTracker.incCounter();
}
- entityManagers.put(entityManagerFactory, entityManager);
+ entityManagers .put(entityManagerFactory,
entityManagerTracker);
}
}
- return entityManagers;
+ return entityManagers ;
}
private void registerEntityManagers(Instance instance, ThreadContext
callContext) throws OpenEJBException {
@@ -773,7 +778,7 @@ public class ManagedContainer implements
if (factories == null) return;
// get the managers for the factories
- Map<EntityManagerFactory, EntityManager> entityManagers =
instance.getEntityManagers(factories);
+ Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers =
instance.getEntityManagers(factories);
if (entityManagers == null) return;
// register them
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java?rev=1145516&r1=1145515&r2=1145516&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java
Tue Jul 12 10:01:47 2011
@@ -17,25 +17,25 @@
*/
package org.apache.openejb.core.stateful;
-import java.io.Serializable;
-import java.io.ObjectStreamException;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Stack;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.persistence.EntityManagerFactory;
-import javax.persistence.EntityManager;
-import javax.transaction.Transaction;
-
import org.apache.openejb.BeanContext;
import
org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.persistence.JtaEntityManagerRegistry;
import org.apache.openejb.spi.ContainerSystem;
import org.apache.openejb.util.Duration;
import org.apache.openejb.util.Index;
import org.apache.openejb.util.PojoSerialization;
+import javax.persistence.EntityManagerFactory;
+import javax.transaction.Transaction;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
public class Instance implements Serializable, Cache.TimeOut {
private static final long serialVersionUID = 2862563626506556542L;
public final BeanContext beanContext;
@@ -51,10 +51,10 @@ public class Instance implements Seriali
// todo if we keyed by an entity manager factory id we would not have to
make this transient and rebuild the index below
// This would require that we crete an id and that we track it
// alternatively, we could use ImmutableArtifact with some read/write
replace magic
- private Map<EntityManagerFactory, EntityManager> entityManagers;
- private final EntityManager[] entityManagerArray;
+ private Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers;
+ private final JtaEntityManagerRegistry.EntityManagerTracker[]
entityManagerArray;
- public Instance(BeanContext beanContext, Object primaryKey, Object bean,
Map<String, Object> interceptors, Map<EntityManagerFactory, EntityManager>
entityManagers) {
+ public Instance(BeanContext beanContext, Object primaryKey, Object bean,
Map<String, Object> interceptors, Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers) {
this.beanContext = beanContext;
this.primaryKey = primaryKey;
this.bean = bean;
@@ -63,7 +63,7 @@ public class Instance implements Seriali
this.entityManagerArray = null;
}
- public Instance(Object deploymentId, Object primaryKey, Object bean,
Map<String, Object> interceptors, EntityManager[] entityManagerArray) {
+ public Instance(Object deploymentId, Object primaryKey, Object bean,
Map<String, Object> interceptors,
JtaEntityManagerRegistry.EntityManagerTracker[] entityManagerArray) {
this.beanContext =
SystemInstance.get().getComponent(ContainerSystem.class).getBeanContext(deploymentId);
if (beanContext == null) {
throw new IllegalArgumentException("Unknown deployment " +
deploymentId);
@@ -120,12 +120,12 @@ public class Instance implements Seriali
}
}
- public synchronized Map<EntityManagerFactory, EntityManager>
getEntityManagers(Index<EntityManagerFactory, Map> factories) {
+ public synchronized Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker>
getEntityManagers(Index<EntityManagerFactory, Map> factories) {
if (entityManagers == null && entityManagerArray != null) {
- entityManagers = new HashMap<EntityManagerFactory,
EntityManager>();
+ entityManagers = new HashMap<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker>();
for (int i = 0; i < entityManagerArray.length; i++) {
EntityManagerFactory entityManagerFactory =
factories.getKey(i);
- EntityManager entityManager = entityManagerArray[i];
+ JtaEntityManagerRegistry.EntityManagerTracker entityManager =
entityManagerArray[i];
entityManagers.put(entityManagerFactory, entityManager);
}
}
@@ -148,7 +148,7 @@ public class Instance implements Seriali
public final Object primaryKey;
public final Object bean;
public final Map<String, Object> interceptors;
- public final EntityManager[] entityManagerArray;
+ public final JtaEntityManagerRegistry.EntityManagerTracker[]
entityManagerArray;
public Serialization(Instance i) {
deploymentId = i.beanContext.getDeploymentID();
@@ -168,7 +168,7 @@ public class Instance implements Seriali
if (i.entityManagerArray != null) {
entityManagerArray = i.entityManagerArray;
} else if (i.entityManagers != null) {
- entityManagerArray = i.entityManagers.values().toArray(new
EntityManager[i.entityManagers.values().size()]);
+ entityManagerArray = i.entityManagers.values().toArray(new
JtaEntityManagerRegistry.EntityManagerTracker[i.entityManagers.values().size()]);
} else {
entityManagerArray = null;
}
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=1145516&r1=1145515&r2=1145516&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
Tue Jul 12 10:01:47 2011
@@ -16,37 +16,6 @@
*/
package org.apache.openejb.core.stateful;
-import java.lang.reflect.Method;
-import java.lang.management.ManagementFactory;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.rmi.dgc.VMID;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import javax.ejb.EJBAccessException;
-import javax.ejb.EJBContext;
-import javax.ejb.EJBException;
-import javax.ejb.EJBHome;
-import javax.ejb.EJBLocalHome;
-import javax.ejb.RemoveException;
-import javax.ejb.SessionBean;
-import javax.ejb.SessionContext;
-import javax.ejb.ConcurrentAccessTimeoutException;
-import javax.enterprise.context.Dependent;
-import javax.enterprise.inject.spi.Bean;
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.persistence.EntityManager;
-import javax.persistence.EntityManagerFactory;
-import javax.transaction.Transaction;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
import org.apache.openejb.ApplicationException;
import org.apache.openejb.BeanContext;
import org.apache.openejb.ContainerType;
@@ -57,17 +26,10 @@ import org.apache.openejb.ProxyInfo;
import org.apache.openejb.RpcContainer;
import org.apache.openejb.SystemException;
import org.apache.openejb.cdi.CdiEjbBean;
-import org.apache.openejb.config.rules.CheckDependsOn;
-import org.apache.openejb.monitoring.StatsInterceptor;
-import org.apache.openejb.monitoring.ObjectNameBuilder;
-import org.apache.openejb.monitoring.ManagedMBean;
import org.apache.openejb.core.ExceptionType;
-import static org.apache.openejb.core.ExceptionType.APPLICATION_ROLLBACK;
-import static org.apache.openejb.core.ExceptionType.SYSTEM;
-
+import org.apache.openejb.core.InstanceContext;
import org.apache.openejb.core.Operation;
import org.apache.openejb.core.ThreadContext;
-import org.apache.openejb.core.InstanceContext;
import org.apache.openejb.core.interceptor.InterceptorData;
import org.apache.openejb.core.interceptor.InterceptorStack;
import org.apache.openejb.core.stateful.Cache.CacheFilter;
@@ -75,21 +37,57 @@ import org.apache.openejb.core.stateful.
import org.apache.openejb.core.transaction.BeanTransactionPolicy;
import
org.apache.openejb.core.transaction.BeanTransactionPolicy.SuspendedTransaction;
import org.apache.openejb.core.transaction.EjbTransactionUtil;
-import static
org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy;
-import static
org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException;
-import static
org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException;
import org.apache.openejb.core.transaction.EjbUserTransaction;
-import org.apache.openejb.core.transaction.TransactionPolicy;
import org.apache.openejb.core.transaction.JtaTransactionPolicy;
+import org.apache.openejb.core.transaction.TransactionPolicy;
import
org.apache.openejb.core.transaction.TransactionPolicy.TransactionSynchronization;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.monitoring.ManagedMBean;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.monitoring.StatsInterceptor;
import org.apache.openejb.persistence.EntityManagerAlreadyRegisteredException;
import org.apache.openejb.persistence.JtaEntityManagerRegistry;
import org.apache.openejb.spi.SecurityService;
+import org.apache.openejb.util.Duration;
import org.apache.openejb.util.Index;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.Duration;
+
+import javax.ejb.ConcurrentAccessTimeoutException;
+import javax.ejb.EJBAccessException;
+import javax.ejb.EJBContext;
+import javax.ejb.EJBException;
+import javax.ejb.EJBHome;
+import javax.ejb.EJBLocalHome;
+import javax.ejb.RemoveException;
+import javax.ejb.SessionBean;
+import javax.ejb.SessionContext;
+import javax.enterprise.context.Dependent;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.transaction.Transaction;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.rmi.NoSuchObjectException;
+import java.rmi.RemoteException;
+import java.rmi.dgc.VMID;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+import static org.apache.openejb.core.ExceptionType.APPLICATION_ROLLBACK;
+import static org.apache.openejb.core.ExceptionType.SYSTEM;
+import static
org.apache.openejb.core.transaction.EjbTransactionUtil.createTransactionPolicy;
+import static
org.apache.openejb.core.transaction.EjbTransactionUtil.handleApplicationException;
+import static
org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemException;
public class StatefulContainer implements RpcContainer {
private static final Logger logger =
Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
@@ -363,7 +361,7 @@ public class StatefulContainer implement
checkAuthorization(callMethod, interfaceType);
// Create the extended entity managers for this instance
- Index<EntityManagerFactory, EntityManager> entityManagers =
createEntityManagers(beanContext);
+ Index<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers =
createEntityManagers(beanContext);
// Register the newly created entity managers
if (entityManagers != null) {
@@ -427,6 +425,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 +559,27 @@ public class StatefulContainer implement
callContext.setCurrentOperation(Operation.REMOVE);
}
- // todo destroy extended persistence contexts
discardInstance(callContext);
}
+ // un register EntityManager
+ Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> 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 +616,7 @@ public class StatefulContainer implement
// Register the entity managers
registerEntityManagers(instance, callContext);
+
// Register for synchronization callbacks
registerSessionSynchronization(instance, callContext);
@@ -619,6 +636,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 +797,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;
@@ -801,26 +820,30 @@ public class StatefulContainer implement
}
}
- private Index<EntityManagerFactory, EntityManager>
createEntityManagers(BeanContext beanContext) {
+ private Index<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> createEntityManagers(BeanContext
beanContext) {
// create the extended entity managers
Index<EntityManagerFactory, Map> factories =
beanContext.getExtendedEntityManagerFactories();
- Index<EntityManagerFactory, EntityManager> entityManagers = null;
+ Index<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers = null;
if (factories != null && factories.size() > 0) {
- entityManagers = new Index<EntityManagerFactory,
EntityManager>(new ArrayList<EntityManagerFactory>(factories.keySet()));
+ entityManagers = new Index<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker>(new
ArrayList<EntityManagerFactory>(factories.keySet()));
for (Map.Entry<EntityManagerFactory, Map> entry :
factories.entrySet()) {
EntityManagerFactory entityManagerFactory = entry.getKey();
Map properties = entry.getValue();
- EntityManager entityManager =
entityManagerRegistry.getInheritedEntityManager(entityManagerFactory);
- if (entityManager == null) {
+ JtaEntityManagerRegistry.EntityManagerTracker
entityManagerTracker =
entityManagerRegistry.getInheritedEntityManager(entityManagerFactory);
+ EntityManager entityManager;
+ if (entityManagerTracker == null) {
if (properties != null) {
entityManager =
entityManagerFactory.createEntityManager(properties);
} else {
entityManager =
entityManagerFactory.createEntityManager();
}
+ entityManagerTracker = new
JtaEntityManagerRegistry.EntityManagerTracker(entityManager);
+ } else {
+ entityManagerTracker.incCounter();
}
- entityManagers.put(entityManagerFactory, entityManager);
+ entityManagers.put(entityManagerFactory, entityManagerTracker);
}
}
return entityManagers;
@@ -836,7 +859,7 @@ public class StatefulContainer implement
if (factories == null) return;
// get the managers for the factories
- Map<EntityManagerFactory, EntityManager> entityManagers =
instance.getEntityManagers(factories);
+ Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker> entityManagers =
instance.getEntityManagers(factories);
if (entityManagers == null) return;
// register them
@@ -847,16 +870,26 @@ public class StatefulContainer implement
}
}
- private void unregisterEntityManagers(Instance instance, ThreadContext
callContext) {
- if (entityManagerRegistry == null) return;
- if (instance == null) return;
+ private Map<EntityManagerFactory,
JtaEntityManagerRegistry.EntityManagerTracker>
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,JtaEntityManagerRegistry.EntityManagerTracker>
unregisteredEntityManagers) {
+ if (unregisteredEntityManagers == null) return;
+
+ // iterate throughout all EM to close EntityManager
+ for (JtaEntityManagerRegistry.EntityManagerTracker
entityManagerTracker : unregisteredEntityManagers.values()) {
+ if(entityManagerTracker.decCounter() == 0) {
+ entityManagerTracker.getEntityManager().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=1145516&r1=1145515&r2=1145516&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
Tue Jul 12 10:01:47 2011
@@ -95,10 +95,11 @@ public class JtaEntityManagerRegistry {
// if extended context, there must be an entity manager already
registered with the tx
if (extended) {
- EntityManager entityManager =
getInheritedEntityManager(entityManagerFactory);
- if (entityManager == null) {
+ EntityManagerTracker entityManagerTracker =
getInheritedEntityManager(entityManagerFactory);
+ if (entityManagerTracker == null ||
entityManagerTracker.getEntityManager() == null) {
throw new IllegalStateException("InternalError: an entity
manager should already be registered for this extended persistence unit");
}
+ EntityManager entityManager =
entityManagerTracker.getEntityManager();
// if transaction is active, we need to register the entity
manager with the transaction manager
if (transactionActive) {
@@ -137,16 +138,17 @@ public class JtaEntityManagerRegistry {
* @throws EntityManagerAlreadyRegisteredException if an entity manager is
already registered with the transaction
* for one of the supplied entity manager factories; for EJBs this should
be caught and rethown as an EJBException
*/
- public void addEntityManagers(String deploymentId, Object primaryKey,
Map<EntityManagerFactory, EntityManager> entityManagers) throws
EntityManagerAlreadyRegisteredException {
+ public void addEntityManagers(String deploymentId, Object primaryKey,
Map<EntityManagerFactory, EntityManagerTracker> entityManagers) throws
EntityManagerAlreadyRegisteredException {
extendedRegistry.get().addEntityManagers(new InstanceId(deploymentId,
primaryKey), entityManagers);
}
/**
* 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, EntityManagerTracker>
removeEntityManagers(String deploymentId, Object primaryKey) {
+ return extendedRegistry.get().removeEntityManagers(new
InstanceId(deploymentId, primaryKey));
}
/**
@@ -154,7 +156,7 @@ public class JtaEntityManagerRegistry {
* @param entityManagerFactory the entity manager factory from which an
entity manager is needed
* @return the existing entity manager or null if one is not found
*/
- public EntityManager getInheritedEntityManager(EntityManagerFactory
entityManagerFactory) {
+ public EntityManagerTracker getInheritedEntityManager(EntityManagerFactory
entityManagerFactory) {
return
extendedRegistry.get().getInheritedEntityManager(entityManagerFactory);
}
@@ -179,10 +181,11 @@ public class JtaEntityManagerRegistry {
}
private class ExtendedRegistry {
- private final Map<InstanceId, Map<EntityManagerFactory,
EntityManager>> entityManagersByDeploymentId =
- new HashMap<InstanceId, Map<EntityManagerFactory,
EntityManager>>();
+ private final Map<InstanceId, Map<EntityManagerFactory,
EntityManagerTracker>> entityManagersByDeploymentId =
+ new HashMap<InstanceId, Map<EntityManagerFactory,
EntityManagerTracker>>();
- private void addEntityManagers(InstanceId instanceId,
Map<EntityManagerFactory, EntityManager> entityManagers) throws
EntityManagerAlreadyRegisteredException {
+ private void addEntityManagers(InstanceId instanceId,
Map<EntityManagerFactory, EntityManagerTracker> entityManagers)
+ throws EntityManagerAlreadyRegisteredException {
if (instanceId == null) {
throw new NullPointerException("instanceId is null");
}
@@ -191,9 +194,9 @@ public class JtaEntityManagerRegistry {
}
if (isTransactionActive()) {
- for (Map.Entry<EntityManagerFactory, EntityManager> entry :
entityManagers.entrySet()) {
+ for (Map.Entry<EntityManagerFactory, EntityManagerTracker>
entry : entityManagers.entrySet()) {
EntityManagerFactory entityManagerFactory = entry.getKey();
- EntityManager entityManager = entry.getValue();
+ EntityManager entityManager =
entry.getValue().getEntityManager();
EntityManagerTxKey txKey = new
EntityManagerTxKey(entityManagerFactory);
EntityManager oldEntityManager = (EntityManager)
transactionRegistry.getResource(txKey);
if (entityManager == oldEntityManager) {
@@ -210,23 +213,23 @@ public class JtaEntityManagerRegistry {
entityManagersByDeploymentId.put(instanceId, entityManagers);
}
- private void removeEntityManagers(InstanceId instanceId) {
+ private Map<EntityManagerFactory, EntityManagerTracker>
removeEntityManagers(InstanceId instanceId) {
if (instanceId == null) {
throw new NullPointerException("InstanceId is null");
}
- entityManagersByDeploymentId.remove(instanceId);
+ return entityManagersByDeploymentId.remove(instanceId);
}
- private EntityManager getInheritedEntityManager(EntityManagerFactory
entityManagerFactory) {
+ private EntityManagerTracker
getInheritedEntityManager(EntityManagerFactory entityManagerFactory) {
if (entityManagerFactory == null) {
throw new NullPointerException("entityManagerFactory is null");
}
- for (Map<EntityManagerFactory, EntityManager> entityManagers :
entityManagersByDeploymentId.values()) {
- EntityManager entityManager =
entityManagers.get(entityManagerFactory);
- if (entityManager != null) {
- return entityManager;
+ for (Map<EntityManagerFactory, EntityManagerTracker>
entityManagers : entityManagersByDeploymentId.values()) {
+ EntityManagerTracker entityManagerTracker =
entityManagers.get(entityManagerFactory);
+ if (entityManagerTracker != null) {
+ return entityManagerTracker;
}
}
return null;
@@ -240,14 +243,14 @@ public class JtaEntityManagerRegistry {
throw new TransactionRequiredException();
}
- Map<EntityManagerFactory, EntityManager> entityManagers =
entityManagersByDeploymentId.get(instanceId);
+ Map<EntityManagerFactory, EntityManagerTracker> entityManagers =
entityManagersByDeploymentId.get(instanceId);
if (entityManagers == null) {
return;
}
- for (Map.Entry<EntityManagerFactory, EntityManager> entry :
entityManagers.entrySet()) {
+ for (Map.Entry<EntityManagerFactory, EntityManagerTracker> entry :
entityManagers.entrySet()) {
EntityManagerFactory entityManagerFactory = entry.getKey();
- EntityManager entityManager = entry.getValue();
+ EntityManager entityManager =
entry.getValue().getEntityManager();
entityManager.joinTransaction();
EntityManagerTxKey txKey = new
EntityManagerTxKey(entityManagerFactory);
transactionRegistry.putResource(txKey, entityManager);
@@ -292,6 +295,36 @@ public class JtaEntityManagerRegistry {
}
}
+ /**
+ * This object is used track all EntityManagers inherited in order
+ * to effectively close it when the latest Extended persistence context
+ * is no more accessed.
+ */
+ public static class EntityManagerTracker {
+ // must take care of the first inheritance level
+ private transient int counter;
+ private EntityManager entityManager;
+
+ public EntityManagerTracker(EntityManager entityManager) {
+ if (entityManager == null) throw new
NullPointerException("entityManager is null.");
+
+ this.counter = 0;
+ this.entityManager = entityManager;
+ }
+
+ public int incCounter() {
+ return counter++;
+ }
+
+ public int decCounter() {
+ return counter--;
+ }
+
+ public EntityManager getEntityManager() {
+ return entityManager;
+ }
+ }
+
private static class CloseEntityManager implements Synchronization {
private final EntityManager entityManager;
private String unitName;
Modified:
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/EntityManagerPropogationTest.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/EntityManagerPropogationTest.java?rev=1145516&r1=1145515&r2=1145516&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/EntityManagerPropogationTest.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/EntityManagerPropogationTest.java
Tue Jul 12 10:01:47 2011
@@ -39,28 +39,53 @@ import org.apache.openjpa.persistence.Ar
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.ejb.Local;
-import javax.ejb.Remove;
import javax.ejb.NoSuchEJBException;
+import javax.ejb.Remove;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.Id;
import javax.persistence.PersistenceContext;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
import static javax.persistence.PersistenceContextType.EXTENDED;
import static javax.persistence.PersistenceContextType.TRANSACTION;
-import java.io.IOException;
public class EntityManagerPropogationTest extends TestCase {
public void test() throws Exception {
+ _testEMClose();
_testExtended();
_testExtendedRemove();
+ _testExtendedRandomRemove();
_testNotTooExtended();
_testTransaction();
- _testSFTr2SFEx();
- _testSFEx2SLTr2SFEx();
- _testSLTr2SFEx();
+ _testSFTr2SFEx();
+ _testSFEx2SLTr2SFEx();
+ _testSLTr2SFEx();
+ }
+
+ private void _testEMClose() throws Exception {
+ InitialContext ctx = new InitialContext();
+
+ PleaseCloseMyExtendedEmBean checkExtendedWorks =
(PleaseCloseMyExtendedEmBean) ctx.lookup("PleaseCloseMyExtendedEmLocalBean");
+ EntityManager savedReference = checkExtendedWorks.getDelegate();
+ checkExtendedWorks.remove();
+ assertFalse(savedReference.isOpen());
+
+ PleaseCloseMyEmBean please = (PleaseCloseMyEmBean)
ctx.lookup("PleaseCloseMyEmLocalBean");
+ savedReference = please.getDelegate();
+ please.remove();
+ assertFalse(savedReference.isOpen());
+
+ PleaseCloseMyEmBean statelessIsEasier = (PleaseCloseMyEmBean)
ctx.lookup("PleaseCloseMyLessEmLocalBean");
+ savedReference = statelessIsEasier.getDelegate();
+ statelessIsEasier.remove();
+ assertFalse(savedReference.isOpen());
}
public void _testExtended() throws Exception {
@@ -117,6 +142,42 @@ public class EntityManagerPropogationTes
}
+ public void _testExtendedRandomRemove() throws Exception {
+
+ InitialContext ctx = new InitialContext();
+ int size;
+ Random rdm = new Random();
+
+ for (int l = 0 ; l < 10 ; l++) { // because Romain is not sure of the
Random ;-)
+ Node node = (Node) ctx.lookup("ExtendedLocalBean");
+ List<Node> nodes = new ArrayList<Node>();
+ List<EntityManager> delegates = new ArrayList<EntityManager>();
+
+ while (node.getChild() != null) {
+ nodes.add(node);
+ delegates.add(node.getDelegateEntityManager());
+ node = node.getChild();
+ }
+
+ // random remove all stateful
+ do {
+ size = nodes.size();
+ int i = rdm.nextInt(size);
+ Node n = nodes.remove(i);
+ EntityManager entityManager = delegates.remove(i);
+
+ n.remove();
+
+ if (--size == 0) {
+ assertFalse(entityManager.isOpen());
+ } else {
+ assertTrue(entityManager.isOpen());
+ }
+
+ } while (size > 0);
+ }
+ }
+
/**
* Test that two Stateful session bean siblings
* do not share the same extended persistence context
@@ -217,7 +278,7 @@ public class EntityManagerPropogationTes
node.createUntilLeaf(8, "Yellow");
fail("5.6.3.1 Requirements for Persistence Context Propagation
(persistence spec)" +
- "\n\t--> we cannot have two persistence contexts
associated with the transaction");
+ "\n\t--> we cannot have two persistence contexts associated
with the transaction");
} catch (EJBException e) {
// OK
@@ -241,6 +302,10 @@ public class EntityManagerPropogationTes
// Create an ejb-jar.xml for this app
EjbJar ejbJar = new EjbJar();
+ ejbJar.addEnterpriseBean(new StatefulBean("PleaseCloseMyExtendedEm",
PleaseCloseMyExtendedEmBean.class));
+ ejbJar.addEnterpriseBean(new StatefulBean("PleaseCloseMyEm",
PleaseCloseMyEmBean.class));
+ ejbJar.addEnterpriseBean(new StatelessBean("PleaseCloseMyLessEm",
PleaseCloseMyEmBean.class));
+
// Add six beans and link them all in a chain
addStatefulBean(ejbJar, ExtendedContextBean.class, "Extended",
"Extendedx2");
addStatefulBean(ejbJar, ExtendedContextBean.class, "Extendedx2",
"Extendedx3");
@@ -349,9 +414,35 @@ public class EntityManagerPropogationTes
Node getChild();
String getDelegateEntityManagerReference();
-
+
+ EntityManager getDelegateEntityManager();
+ }
+
+ public static class PleaseCloseMyExtendedEmBean {
+
+ @PersistenceContext(unitName = "testUnit", type = EXTENDED)
+ protected EntityManager context;
+
+ public EntityManager getDelegate() {
+ return (EntityManager) context.getDelegate();
+ }
+
+ @Remove
+ public void remove(){}
}
+ public static class PleaseCloseMyEmBean {
+
+ @PersistenceContext(unitName = "testUnit", type = TRANSACTION)
+ protected EntityManager context;
+
+ public EntityManager getDelegate() {
+ return (EntityManager) context.getDelegate();
+ }
+
+ @Remove
+ public void remove(){}
+ }
/**
* The root stateful session bean is essentially the "owner"
@@ -371,6 +462,10 @@ public class EntityManagerPropogationTes
protected EntityManager getEntityManager() {
return context;
}
+
+ public EntityManager getDelegateEntityManager() {
+ return (EntityManager) context.getDelegate();
+ }
}
public static class TransactionContextBean extends NodeBean {
@@ -381,6 +476,10 @@ public class EntityManagerPropogationTes
protected EntityManager getEntityManager() {
return context;
}
+
+ public EntityManager getDelegateEntityManager() {
+ return (EntityManager) context.getDelegate();
+ }
}
public static abstract class NodeBean implements Node {
@@ -444,6 +543,10 @@ public class EntityManagerPropogationTes
return null;
}
+ public EntityManager getDelegateEntityManager() {
+ return null;
+ }
+
@Remove
public void remove(){}