TOMEE-1644 handling synchronization type for extended emf
Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/d1a17c6a Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/d1a17c6a Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/d1a17c6a Branch: refs/heads/tomee-7.0.0-M1 Commit: d1a17c6a24aabbcda6504bbd0a39a52df375216b Parents: dc45934 Author: Romain Manni-Bucau <rmann...@gmail.com> Authored: Fri Oct 23 12:33:18 2015 +0200 Committer: Romain Manni-Bucau <rmann...@gmail.com> Committed: Fri Oct 23 12:33:18 2015 +0200 ---------------------------------------------------------------------- .../java/org/apache/openejb/BeanContext.java | 25 +++++++++++++++++--- .../classic/EnterpriseBeanBuilder.java | 23 +++++++++++------- .../apache/openejb/core/managed/Instance.java | 5 ++-- .../openejb/core/managed/ManagedContainer.java | 18 ++++++++++---- .../apache/openejb/core/stateful/Instance.java | 5 ++-- .../core/stateful/StatefulContainer.java | 22 +++++++++++------ .../openejb/persistence/JtaEntityManager.java | 2 +- .../openejb/cdi/ProducedExtendedEmTest.java | 4 +++- 8 files changed, 75 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/d1a17c6a/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java b/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java index 45582e3..a33fb5f 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/BeanContext.java @@ -79,6 +79,7 @@ import javax.enterprise.inject.spi.InterceptionType; import javax.enterprise.inject.spi.Interceptor; import javax.naming.Context; import javax.persistence.EntityManagerFactory; +import javax.persistence.SynchronizationType; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; @@ -757,11 +758,11 @@ public class BeanContext extends DeploymentContext { return injections; } - public Index<EntityManagerFactory, Map> getExtendedEntityManagerFactories() { + public Index<EntityManagerFactory, EntityManagerConfiguration> getExtendedEntityManagerFactories() { return getStateful().extendedEntityManagerFactories; } - public void setExtendedEntityManagerFactories(final Index<EntityManagerFactory, Map> extendedEntityManagerFactories) { + public void setExtendedEntityManagerFactories(final Index<EntityManagerFactory, EntityManagerConfiguration> extendedEntityManagerFactories) { this.getStateful().extendedEntityManagerFactories = extendedEntityManagerFactories; } @@ -1934,7 +1935,7 @@ public class BeanContext extends DeploymentContext { private static class Stateful { - private Index<EntityManagerFactory, Map> extendedEntityManagerFactories; + private Index<EntityManagerFactory, EntityManagerConfiguration> extendedEntityManagerFactories; private Duration statefulTimeout; private final List<Method> removeMethods = new ArrayList<Method>(); } @@ -1972,4 +1973,22 @@ public class BeanContext extends DeploymentContext { return proxy; // let it generate a NPE if null, shouldn't occur (tested elsewhere) excepted for test where we don't use it } } + + public static class EntityManagerConfiguration { + private final Map properties; + private final SynchronizationType synchronizationType; + + public EntityManagerConfiguration(final Map properties, final SynchronizationType synchronizationType) { + this.properties = properties; + this.synchronizationType = synchronizationType; + } + + public Map getProperties() { + return properties; + } + + public SynchronizationType getSynchronizationType() { + return synchronizationType; + } + } } http://git-wip-us.apache.org/repos/asf/tomee/blob/d1a17c6a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java index 721a73f..2b819ba 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java @@ -25,11 +25,18 @@ import org.apache.openejb.OpenEJBException; import org.apache.openejb.core.cmp.CmpUtil; import org.apache.openejb.dyni.DynamicSubclass; import org.apache.openejb.loader.SystemInstance; +import org.apache.openejb.persistence.JtaEntityManager; import org.apache.openejb.spi.ContainerSystem; import org.apache.openejb.util.Duration; import org.apache.openejb.util.Index; import org.apache.openejb.util.Messages; +import javax.ejb.TimedObject; +import javax.ejb.Timer; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.persistence.EntityManagerFactory; +import javax.persistence.SynchronizationType; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -39,11 +46,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; -import javax.ejb.TimedObject; -import javax.ejb.Timer; -import javax.naming.Context; -import javax.naming.NamingException; -import javax.persistence.EntityManagerFactory; class EnterpriseBeanBuilder { private final EnterpriseBeanInfo bean; @@ -231,20 +233,25 @@ class EnterpriseBeanBuilder { } - final Map<EntityManagerFactory, Map> extendedEntityManagerFactories = new HashMap<EntityManagerFactory, Map>(); + final Map<EntityManagerFactory, BeanContext.EntityManagerConfiguration> extendedEntityManagerFactories = new HashMap<>(); for (final PersistenceContextReferenceInfo info : statefulBeanInfo.jndiEnc.persistenceContextRefs) { if (info.extended) { try { final ContainerSystem containerSystem = SystemInstance.get().getComponent(ContainerSystem.class); final Object o = containerSystem.getJNDIContext().lookup(PersistenceBuilder.getOpenEJBJndiName(info.unitId)); - extendedEntityManagerFactories.put((EntityManagerFactory) o, info.properties); + final EntityManagerFactory emf = EntityManagerFactory.class.cast(o); + extendedEntityManagerFactories.put( + emf, + new BeanContext.EntityManagerConfiguration( + info.properties, + JtaEntityManager.isJPA21(emf) && info.synchronizationType != null ? SynchronizationType.valueOf(info.synchronizationType) : null)); } catch (final NamingException e) { throw new OpenEJBException("PersistenceUnit '" + info.unitId + "' not found for EXTENDED ref '" + info.referenceName + "'"); } } } - deployment.setExtendedEntityManagerFactories(new Index<EntityManagerFactory, Map>(extendedEntityManagerFactories)); + deployment.setExtendedEntityManagerFactories(new Index<>(extendedEntityManagerFactories)); } if (ejbType.isSession() || ejbType.isMessageDriven()) { http://git-wip-us.apache.org/repos/asf/tomee/blob/d1a17c6a/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java b/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java index ff4ac41..e02456b 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/core/managed/Instance.java @@ -124,9 +124,10 @@ public class Instance implements Serializable { } } - public synchronized Map<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> getEntityManagers(final Index<EntityManagerFactory, Map> factories) { + public synchronized Map<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> getEntityManagers( + final Index<EntityManagerFactory, BeanContext.EntityManagerConfiguration> factories) { if (entityManagers == null && entityManagerArray != null) { - entityManagers = new HashMap<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker>(); + entityManagers = new HashMap<>(); for (int i = 0; i < entityManagerArray.length; i++) { final EntityManagerFactory entityManagerFactory = factories.getKey(i); final JtaEntityManagerRegistry.EntityManagerTracker entityManager = entityManagerArray[i]; http://git-wip-us.apache.org/repos/asf/tomee/blob/d1a17c6a/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java index 9bc1c99..b0bbfc6 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/core/managed/ManagedContainer.java @@ -69,6 +69,7 @@ import javax.naming.Context; import javax.naming.NamingException; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; +import javax.persistence.SynchronizationType; import javax.transaction.Transaction; import java.lang.reflect.Method; import java.rmi.NoSuchObjectException; @@ -776,18 +777,25 @@ public class ManagedContainer implements RpcContainer { private Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> createEntityManagers(final BeanContext beanContext) { // create the extended entity managers - final Index<EntityManagerFactory, Map> factories = beanContext.getExtendedEntityManagerFactories(); + final Index<EntityManagerFactory, BeanContext.EntityManagerConfiguration> factories = beanContext.getExtendedEntityManagerFactories(); Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> entityManagers = null; if (factories != null && factories.size() > 0) { entityManagers = new Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker>(new ArrayList<EntityManagerFactory>(factories.keySet())); - for (final Map.Entry<EntityManagerFactory, Map> entry : factories.entrySet()) { + for (final Map.Entry<EntityManagerFactory, BeanContext.EntityManagerConfiguration> entry : factories.entrySet()) { final EntityManagerFactory entityManagerFactory = entry.getKey(); - final Map properties = entry.getValue(); JtaEntityManagerRegistry.EntityManagerTracker entityManagerTracker = entityManagerRegistry.getInheritedEntityManager(entityManagerFactory); final EntityManager entityManager; if (entityManagerTracker == null) { - if (properties != null) { + final SynchronizationType synchronizationType = entry.getValue().getSynchronizationType(); + final Map properties = entry.getValue().getProperties(); + if (synchronizationType != null) { + if (properties != null) { + entityManager = entityManagerFactory.createEntityManager(synchronizationType, properties); + } else { + entityManager = entityManagerFactory.createEntityManager(synchronizationType); + } + } else if (properties != null) { entityManager = entityManagerFactory.createEntityManager(properties); } else { entityManager = entityManagerFactory.createEntityManager(); @@ -810,7 +818,7 @@ public class ManagedContainer implements RpcContainer { final BeanContext beanContext = callContext.getBeanContext(); // get the factories - final Index<EntityManagerFactory, Map> factories = beanContext.getExtendedEntityManagerFactories(); + final Index<EntityManagerFactory, BeanContext.EntityManagerConfiguration> factories = beanContext.getExtendedEntityManagerFactories(); if (factories == null) { return; } http://git-wip-us.apache.org/repos/asf/tomee/blob/d1a17c6a/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java b/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java index 815922d..0e6b6f1 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java @@ -133,9 +133,10 @@ public class Instance implements Serializable, Cache.TimeOut { } } - public synchronized Map<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> getEntityManagers(final Index<EntityManagerFactory, Map> factories) { + public synchronized Map<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> getEntityManagers( + final Index<EntityManagerFactory, BeanContext.EntityManagerConfiguration> factories) { if (entityManagers == null && entityManagerArray != null) { - entityManagers = new HashMap<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker>(); + entityManagers = new HashMap<>(); for (int i = 0; i < entityManagerArray.length; i++) { final EntityManagerFactory entityManagerFactory = factories.getKey(i); final JtaEntityManagerRegistry.EntityManagerTracker entityManager = entityManagerArray[i]; http://git-wip-us.apache.org/repos/asf/tomee/blob/d1a17c6a/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java b/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java index 4df52fd..7a5f6ee 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java @@ -73,6 +73,7 @@ import javax.naming.Context; import javax.naming.NamingException; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; +import javax.persistence.SynchronizationType; import javax.transaction.Transaction; import java.io.Serializable; import java.lang.reflect.Method; @@ -381,7 +382,7 @@ public class StatefulContainer implements RpcContainer { if (preventExtendedEntityManagerSerialization) { return true; } - final Index<EntityManagerFactory, Map> factories = beanContext.getExtendedEntityManagerFactories(); + final Index<EntityManagerFactory, BeanContext.EntityManagerConfiguration> factories = beanContext.getExtendedEntityManagerFactories(); return !(factories != null && factories.size() > 0) && beanContext.isPassivable(); } @@ -889,18 +890,25 @@ public class StatefulContainer implements RpcContainer { private Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> createEntityManagers(final BeanContext beanContext) { // create the extended entity managers - final Index<EntityManagerFactory, Map> factories = beanContext.getExtendedEntityManagerFactories(); + final Index<EntityManagerFactory, BeanContext.EntityManagerConfiguration> factories = beanContext.getExtendedEntityManagerFactories(); Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> entityManagers = null; if (factories != null && factories.size() > 0) { - entityManagers = new Index<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker>(new ArrayList<EntityManagerFactory>(factories.keySet())); - for (final Map.Entry<EntityManagerFactory, Map> entry : factories.entrySet()) { + entityManagers = new Index<>(new ArrayList<>(factories.keySet())); + for (final Map.Entry<EntityManagerFactory, BeanContext.EntityManagerConfiguration> entry : factories.entrySet()) { final EntityManagerFactory entityManagerFactory = entry.getKey(); - final Map properties = entry.getValue(); JtaEntityManagerRegistry.EntityManagerTracker entityManagerTracker = entityManagerRegistry.getInheritedEntityManager(entityManagerFactory); final EntityManager entityManager; if (entityManagerTracker == null) { - if (properties != null) { + final Map properties = entry.getValue().getProperties(); + final SynchronizationType synchronizationType = entry.getValue().getSynchronizationType(); + if (synchronizationType != null) { + if (properties != null) { + entityManager = entityManagerFactory.createEntityManager(synchronizationType, properties); + } else { + entityManager = entityManagerFactory.createEntityManager(synchronizationType); + } + } else if (properties != null) { entityManager = entityManagerFactory.createEntityManager(properties); } else { entityManager = entityManagerFactory.createEntityManager(); @@ -923,7 +931,7 @@ public class StatefulContainer implements RpcContainer { final BeanContext beanContext = callContext.getBeanContext(); // get the factories - final Index<EntityManagerFactory, Map> factories = beanContext.getExtendedEntityManagerFactories(); + final Index<EntityManagerFactory, BeanContext.EntityManagerConfiguration> factories = beanContext.getExtendedEntityManagerFactories(); if (factories == null) { return; } http://git-wip-us.apache.org/repos/asf/tomee/blob/d1a17c6a/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java b/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java index 918331b..208f6d5 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/persistence/JtaEntityManager.java @@ -118,7 +118,7 @@ public class JtaEntityManager implements EntityManager, Serializable { this.wrapNoTxQueries = wrapConfig == null || "true".equalsIgnoreCase(wrapConfig); } - private static boolean isJPA21(final EntityManagerFactory entityManagerFactory) { + public static boolean isJPA21(final EntityManagerFactory entityManagerFactory) { return ReloadableEntityManagerFactory.class.isInstance(entityManagerFactory) ? isJPA21(ReloadableEntityManagerFactory.class.cast(entityManagerFactory).getDelegate()) : hasMethod(entityManagerFactory, "createEntityManager", SynchronizationType.class); http://git-wip-us.apache.org/repos/asf/tomee/blob/d1a17c6a/container/openejb-core/src/test/java/org/apache/openejb/cdi/ProducedExtendedEmTest.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/test/java/org/apache/openejb/cdi/ProducedExtendedEmTest.java b/container/openejb-core/src/test/java/org/apache/openejb/cdi/ProducedExtendedEmTest.java index 2533625..d1c35d5 100644 --- a/container/openejb-core/src/test/java/org/apache/openejb/cdi/ProducedExtendedEmTest.java +++ b/container/openejb-core/src/test/java/org/apache/openejb/cdi/ProducedExtendedEmTest.java @@ -96,11 +96,13 @@ public class ProducedExtendedEmTest { private A a; @Test - @Ignore("will be done thanks to OWB new impl") public void checkEm() { try { a.getDelegateClassName(); } catch (final EJBException ee) { + // an entity manager should already be registered for this extended persistence unit + // valid since we dont call it in the context of the stateful + // note: we could enhance it later if needed assertNotNull(ee); assertThat(ee.getCause(), instanceOf(IllegalStateException.class)); }