Hi guys,

a quick note on that commit (and if you have a better idea it would be very
very welcomed).

Issue is JPA needs to know the BeanManager reference now.

First idea was to start CDI before JPA (yes it breaks the class
transformation lifecycle but let's assume it doesn't). Issue is then if CDI
uses a startup event then JPA can be missing and the app will not boot.

So we need to start JPA before CDI but hibernate for instance uses CDI when
the EMF is created to lookup the listeners in CDI context...which fails
cause CDI is not yet booted.

I don't see a good solution to that so I basically made a proxy to the bean
manager available to JPA and added a property to support the lazy creation
of the EMF (see https://issues.apache.org/jira/browse/TOMEE-1951).

It seems it works - I expect some test to break but will keep an eye on
that - but it can break some tomee 7.0.[0|1] applications relying on
hibernate (maybe eclipselink, didnt check yet but build will say us) and
I'm not very happy of that state even if it is the best I found.

Wanted to avoid to do some kind of reactive implementation popping up
threads "on demand" which would make the application quite uncontrolled
compared to what we do today which is quite predictable.

Happy to get help on that topic if you see a small hole we can use to make
it smoother.

Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://blog-rmannibucau.rhcloud.com> | Old Wordpress Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Tomitriber
<http://www.tomitribe.com> | JavaEE Factory
<https://javaeefactory-rmannibucau.rhcloud.com>

---------- Forwarded message ----------
From: <rmannibu...@apache.org>
Date: 2016-10-03 11:03 GMT+02:00
Subject: tomee git commit: TOMEE-1951 making JPA CDI aware
To: comm...@tomee.apache.org


Repository: tomee
Updated Branches:
  refs/heads/master 63792008e -> 0737513ae


TOMEE-1951 making JPA CDI aware


Project: http://git-wip-us.apache.org/repos/asf/tomee/repo
Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/0737513a
Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/0737513a
Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/0737513a

Branch: refs/heads/master
Commit: 0737513ae6e4755ac94699b3b8b09ee2371ece09
Parents: 6379200
Author: rmannibucau <rmannibu...@apache.org>
Authored: Mon Oct 3 11:02:59 2016 +0200
Committer: rmannibucau <rmannibu...@apache.org>
Committed: Mon Oct 3 11:02:59 2016 +0200

----------------------------------------------------------------------
 .../openejb/assembler/classic/Assembler.java    |   6 +-
 .../classic/EntityManagerFactoryCallable.java   |  53 +++++++-
 .../assembler/classic/PersistenceBuilder.java   |   9 +-
 .../classic/ReloadableEntityManagerFactory.java |  47 ++++---
 .../openejb/persistence/JtaEntityManager.java   |   9 +-
 .../openejb/jpa/JPAHasBeanManagerTest.java      | 121 +++++++++++++++++++
 6 files changed, 216 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tomee/blob/0737513a/
container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/Assembler.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/Assembler.java b/container/openejb-core/src/
main/java/org/apache/openejb/assembler/classic/Assembler.java
index ae52f14..08eb1a3 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/Assembler.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/Assembler.java
@@ -765,6 +765,8 @@ public class Assembler extends AssemblerTool implements
org.apache.openejb.spi.A
             final Map<String, Object> appBindings =
appBuilder.buildBindings(JndiEncBuilder.JndiScope.app);
             final Context appJndiContext = appBuilder.build(appBindings);

+            final boolean cdiActive = shouldStartCdi(appInfo);
+
             try {
                 // Generate the cmp2/cmp1 concrete subclasses
                 final CmpJarBuilder cmpJarBuilder = new
CmpJarBuilder(appInfo, classLoader);
@@ -861,7 +863,7 @@ public class Assembler extends AssemblerTool implements
org.apache.openejb.spi.A
                 for (final PersistenceUnitInfo info :
appInfo.persistenceUnits) {
                     final ReloadableEntityManagerFactory factory;
                     try {
-                        factory = persistenceBuilder.
createEntityManagerFactory(info, classLoader, validatorFactoriesByConfig);
+                        factory = persistenceBuilder.
createEntityManagerFactory(info, classLoader, validatorFactoriesByConfig,
cdiActive);
                         containerSystem.getJNDIContext().bind(
PERSISTENCE_UNIT_NAMING_CONTEXT + info.id, factory);
                         units.put(info.name, PERSISTENCE_UNIT_NAMING_CONTEXT
+ info.id);
                     } catch (final NameAlreadyBoundException e) {
@@ -907,7 +909,7 @@ public class Assembler extends AssemblerTool implements
org.apache.openejb.spi.A
                     propagateApplicationExceptions(appInfo, classLoader,
allDeployments);
                 }

-                if (shouldStartCdi(appInfo)) {
+                if (cdiActive) {
                     new CdiBuilder().build(appInfo, appContext,
allDeployments);
                     ensureWebBeansContext(appContext);
                     appJndiContext.bind("app/BeanManager",
appContext.getBeanManager());

http://git-wip-us.apache.org/repos/asf/tomee/blob/0737513a/
container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
EntityManagerFactoryCallable.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/EntityManagerFactoryCallable.java
b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
EntityManagerFactoryCallable.java
index cb5706b..854c9c4 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/EntityManagerFactoryCallable.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/EntityManagerFactoryCallable.java
@@ -19,11 +19,20 @@ package org.apache.openejb.assembler.classic;

 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.persistence.PersistenceUnitInfoImpl;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.container.InjectableBeanManager;

+import javax.enterprise.inject.spi.BeanManager;
 import javax.persistence.EntityManagerFactory;
 import javax.persistence.ValidationMode;
 import javax.persistence.spi.PersistenceProvider;
 import javax.validation.ValidatorFactory;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Callable;
@@ -35,14 +44,29 @@ public class EntityManagerFactoryCallable implements
Callable<EntityManagerFacto
     private final String persistenceProviderClassName;
     private final PersistenceUnitInfoImpl unitInfo;
     private final Map<ComparableValidationConfig, ValidatorFactory>
potentialValidators;
+    private final boolean cdi;
     private ClassLoader appClassLoader;

     public EntityManagerFactoryCallable(final String
persistenceProviderClassName, final PersistenceUnitInfoImpl unitInfo,
-                                        final ClassLoader cl, final
Map<ComparableValidationConfig,
ValidatorFactory> validators) {
+                                        final ClassLoader cl, final
Map<ComparableValidationConfig,
ValidatorFactory> validators,
+                                        final boolean hasCdi) {
         this.persistenceProviderClassName = persistenceProviderClassName;
         this.unitInfo = unitInfo;
         this.appClassLoader = cl;
         this.potentialValidators = validators;
+        this.cdi = hasCdi;
+    }
+
+    public Class<?> getProvider() {
+        final ClassLoader old = Thread.currentThread().
getContextClassLoader();
+        Thread.currentThread().setContextClassLoader(appClassLoader);
+        try {
+            return appClassLoader.loadClass(persistenceProviderClassName);
+        } catch (final ClassNotFoundException e) {
+            throw new IllegalArgumentException(e);
+        } finally {
+            Thread.currentThread().setContextClassLoader(old);
+        }
     }

     @Override
@@ -58,14 +82,37 @@ public class EntityManagerFactoryCallable implements
Callable<EntityManagerFacto
             if (!ValidationMode.NONE.equals(unitInfo.getValidationMode()))
{
                 properties.put("javax.persistence.validation.factory", new
ValidatorFactoryWrapper(potentialValidators));
             }
+            if (cdi &&
"true".equalsIgnoreCase(unitInfo.getProperties().getProperty("tomee.jpa.cdi",
"true"))
+                    &&
"true".equalsIgnoreCase(SystemInstance.get().getProperty("tomee.jpa.cdi",
"true"))) {
+                properties.put("javax.persistence.bean.manager", // TODO:
impl a passthrough BM?
+                        Proxy.newProxyInstance(appClassLoader, new
Class<?>[]{BeanManager.class}, new InvocationHandler() {
+                            private volatile BeanManager bm;
+
+                            @Override
+                            public Object invoke(final Object proxy, final
Method method, final Object[] args) throws Throwable {
+                                try {
+                                    return method.invoke(findBm(), args);
+                                } catch (final InvocationTargetException
ite) {
+
Logger.getInstance(LogCategory.OPENEJB_JPA,
EntityManagerFactoryCallable.class)
+                                            .warning("Exception calling
CDI, if a lifecycle issue you should maybe set
tomee.jpa.factory.lazy=true", ite.getCause());
+                                    throw ite.getCause();
+                                }
+                            }
+
+                            private Object findBm() {
+                                return bm != null ? bm : (bm = new
InjectableBeanManager(WebBeansContext.currentInstance().
getBeanManagerImpl()));
+                            }
+                        })
+                );
+            }

             customizeProperties(properties);

             final EntityManagerFactory emf = persistenceProvider.
createContainerEntityManagerFactory(unitInfo, properties);

             if (unitInfo.getProperties() != null
-                && "true".equalsIgnoreCase(unitInfo.getProperties().
getProperty(OPENEJB_JPA_INIT_ENTITYMANAGER))
-                ||
SystemInstance.get().getOptions().get(OPENEJB_JPA_INIT_ENTITYMANAGER,
false)) {
+                    && "true".equalsIgnoreCase(unitInfo.getProperties().
getProperty(OPENEJB_JPA_INIT_ENTITYMANAGER))
+                    ||
SystemInstance.get().getOptions().get(OPENEJB_JPA_INIT_ENTITYMANAGER,
false)) {
                 emf.createEntityManager().close();
             }


http://git-wip-us.apache.org/repos/asf/tomee/blob/0737513a/
container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
PersistenceBuilder.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/PersistenceBuilder.java b/container/openejb-core/src/
main/java/org/apache/openejb/assembler/classic/PersistenceBuilder.java
index 992404e..5a54b21 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/PersistenceBuilder.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/PersistenceBuilder.java
@@ -25,7 +25,6 @@ import org.apache.openejb.spi.ContainerSystem;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;

-import java.util.Map;
 import javax.naming.Context;
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
@@ -35,6 +34,7 @@ import javax.persistence.spi.
PersistenceUnitTransactionType;
 import javax.sql.CommonDataSource;
 import javax.sql.DataSource;
 import javax.validation.ValidatorFactory;
+import java.util.Map;

 public class PersistenceBuilder {

@@ -50,7 +50,8 @@ public class PersistenceBuilder {
     }

     public ReloadableEntityManagerFactory createEntityManagerFactory(final
PersistenceUnitInfo info, final ClassLoader classLoader,
-                                                                     final
Map<ComparableValidationConfig, ValidatorFactory> validators) throws
Exception {
+                                                                     final
Map<ComparableValidationConfig, ValidatorFactory> validators,
+                                                                     final
boolean hasCdi) throws Exception {
         final PersistenceUnitInfoImpl unitInfo = new
PersistenceUnitInfoImpl(persistenceClassLoaderHandler);

         // Persistence Unit Id
@@ -68,7 +69,7 @@ public class PersistenceBuilder {
         // Exclude Unlisted Classes
         unitInfo.setExcludeUnlistedClasses(info.excludeUnlistedClasses);

-        unitInfo.setLazilyInitialized(info.webappName != null);
+        unitInfo.setLazilyInitialized(info.webappName != null ||
"true".equalsIgnoreCase(info.properties.getProperty("tomee.jpa.factory.lazy",
"false")));

         final Context context = SystemInstance.get().
getComponent(ContainerSystem.class).getJNDIContext();

@@ -151,7 +152,7 @@ public class PersistenceBuilder {
         final String persistenceProviderClassName = unitInfo.
getPersistenceProviderClassName();
         unitInfo.setPersistenceProviderClassName(
persistenceProviderClassName);

-        final EntityManagerFactoryCallable callable = new
EntityManagerFactoryCallable(persistenceProviderClassName, unitInfo,
classLoader, validators);
+        final EntityManagerFactoryCallable callable = new
EntityManagerFactoryCallable(persistenceProviderClassName, unitInfo,
classLoader, validators, hasCdi);
         return new ReloadableEntityManagerFactory(classLoader, callable,
unitInfo);
     }


http://git-wip-us.apache.org/repos/asf/tomee/blob/0737513a/
container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
ReloadableEntityManagerFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/ReloadableEntityManagerFactory.java
b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
ReloadableEntityManagerFactory.java
index c61b207..a9ba815 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/ReloadableEntityManagerFactory.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/
assembler/classic/ReloadableEntityManagerFactory.java
@@ -86,7 +86,7 @@ public class ReloadableEntityManagerFactory implements
EntityManagerFactory, Ser

     private final PersistenceUnitInfoImpl unitInfoImpl;
     private ClassLoader classLoader;
-    private EntityManagerFactory delegate;
+    private volatile EntityManagerFactory delegate;
     private final EntityManagerFactoryCallable
entityManagerFactoryCallable;
     private ObjectName objectName;

@@ -112,6 +112,21 @@ public class ReloadableEntityManagerFactory implements
EntityManagerFactory, Ser
         unitInfoImpl.setClassLoader(loader);
     }

+    public EntityManagerFactoryCallable getEntityManagerFactoryCallable() {
+        return entityManagerFactoryCallable;
+    }
+
+    private EntityManagerFactory delegate() {
+        if (delegate == null) {
+            synchronized (this) {
+                if (delegate == null) {
+                    createDelegate();
+                }
+            }
+        }
+        return delegate;
+    }
+
     public void createDelegate() {
         JPAThreadContext.infos.put("properties",
entityManagerFactoryCallable.getUnitInfo().getProperties());
         final long start = System.nanoTime();
@@ -145,7 +160,7 @@ public class ReloadableEntityManagerFactory implements
EntityManagerFactory, Ser
     public EntityManager createEntityManager() {
         EntityManager em;
         try {
-            em = delegate.createEntityManager();
+            em = delegate().createEntityManager();
         } catch (final LinkageError le) {
             em = delegate.createEntityManager();
         }
@@ -160,7 +175,7 @@ public class ReloadableEntityManagerFactory implements
EntityManagerFactory, Ser
     public EntityManager createEntityManager(final Map map) {
         EntityManager em;
         try {
-            em = delegate.createEntityManager(map);
+            em = delegate().createEntityManager(map);
         } catch (final LinkageError le) {
             em = delegate.createEntityManager(map);
         }
@@ -175,7 +190,7 @@ public class ReloadableEntityManagerFactory implements
EntityManagerFactory, Ser
     public EntityManager createEntityManager(final SynchronizationType
synchronizationType) {
         EntityManager em;
         try {
-            em = delegate.createEntityManager(synchronizationType);
+            em = delegate().createEntityManager(synchronizationType);
         } catch (final LinkageError le) {
             em = delegate.createEntityManager(synchronizationType);
         }
@@ -190,7 +205,7 @@ public class ReloadableEntityManagerFactory implements
EntityManagerFactory, Ser
     public EntityManager createEntityManager(final SynchronizationType
synchronizationType, final Map map) {
         EntityManager em;
         try {
-            em = delegate.createEntityManager(synchronizationType, map);
+            em = delegate().createEntityManager(synchronizationType, map);
         } catch (final LinkageError le) {
             em = delegate.createEntityManager(synchronizationType, map);
         }
@@ -206,56 +221,56 @@ public class ReloadableEntityManagerFactory
implements EntityManagerFactory, Ser
         if (cls.isAssignableFrom(getClass())) {
             return cls.cast(this);
         }
-        return delegate.unwrap(cls);
+        return delegate().unwrap(cls);
     }

     @Override
     public void addNamedQuery(final String name, final Query query) {
-        delegate.addNamedQuery(name, query);
+        delegate().addNamedQuery(name, query);
     }

     @Override
     public <T> void addNamedEntityGraph(final String graphName, final
EntityGraph<T> entityGraph) {
-        delegate.addNamedEntityGraph(graphName, entityGraph);
+        delegate().addNamedEntityGraph(graphName, entityGraph);
     }

     @Override
     public CriteriaBuilder getCriteriaBuilder() {
-        return delegate.getCriteriaBuilder();
+        return delegate().getCriteriaBuilder();
     }

     @Override
     public Metamodel getMetamodel() {
-        return delegate.getMetamodel();
+        return delegate().getMetamodel();
     }

     @Override
     public boolean isOpen() {
-        return delegate.isOpen();
+        return delegate().isOpen();
     }

     @Override
     public void close() {
-        delegate.close();
+        delegate().close();
     }

     @Override
     public Map<String, Object> getProperties() {
-        return delegate.getProperties();
+        return delegate().getProperties();
     }

     @Override
     public Cache getCache() {
-        return delegate.getCache();
+        return delegate().getCache();
     }

     @Override
     public PersistenceUnitUtil getPersistenceUnitUtil() {
-        return delegate.getPersistenceUnitUtil();
+        return delegate().getPersistenceUnitUtil();
     }

     public EntityManagerFactory getDelegate() {
-        return delegate;
+        return delegate();
     }

     public void register() throws OpenEJBException {

http://git-wip-us.apache.org/repos/asf/tomee/blob/0737513a/
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 208f6d5..79d3154 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
@@ -120,13 +120,14 @@ public class JtaEntityManager implements
EntityManager, Serializable {

     public static boolean isJPA21(final EntityManagerFactory
entityManagerFactory) {
         return
ReloadableEntityManagerFactory.class.isInstance(entityManagerFactory)
?
-                isJPA21(ReloadableEntityManagerFactory.class.cast(
entityManagerFactory).getDelegate())
-                : hasMethod(entityManagerFactory, "createEntityManager",
SynchronizationType.class);
+                hasMethod(
+                        ReloadableEntityManagerFactory.class.cast(
entityManagerFactory).getEntityManagerFactoryCallable().getProvider(),
+                        "createEntityManager", SynchronizationType.class)
+                : hasMethod(entityManagerFactory.getClass(),
"createEntityManager", SynchronizationType.class);
     }

-    private static boolean hasMethod(final Object object, final String
name, final Class<?>... params) {
+    private static boolean hasMethod(final Class<?> objectClass, final
String name, final Class<?>... params) {
         try {
-            final Class<?> objectClass = object.getClass();
             Boolean result = IS_JPA21.get(objectClass);
             if (result == null) {
                 result = !Modifier.isAbstract(objectClass.getMethod(name,
params).getModifiers());

http://git-wip-us.apache.org/repos/asf/tomee/blob/0737513a/
container/openejb-core/src/test/java/org/apache/openejb/
jpa/JPAHasBeanManagerTest.java
----------------------------------------------------------------------
diff --git 
a/container/openejb-core/src/test/java/org/apache/openejb/jpa/JPAHasBeanManagerTest.java
b/container/openejb-core/src/test/java/org/apache/openejb/
jpa/JPAHasBeanManagerTest.java
new file mode 100644
index 0000000..9e42db3
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/
jpa/JPAHasBeanManagerTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.jpa;
+
+import org.apache.openejb.api.configuration.PersistenceUnitDefinition;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.Classes;
+import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
+import org.apache.openjpa.persistence.PersistenceProviderImpl;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.PostConstruct;
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Initialized;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.persistence.Entity;
+import javax.persistence.EntityManager;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.PersistenceContext;
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.transaction.Transactional;
+import java.util.Map;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+@Classes(cdi = true, innerClassesAsBean = true)
+@RunWith(ApplicationComposer.class)
+public class JPAHasBeanManagerTest {
+    @Inject
+    private Dao dao;
+
+    @Test
+    public void run() {
+        dao.doAsserts();
+    }
+
+    @Transactional
+    @ApplicationScoped
+    @PersistenceUnitDefinition(
+            entitiesPackage = "org.apache.openejb.jpa",
+            properties = {"openjpa.RuntimeUnenhancedClasses=supported",
"tomee.jpa.factory.lazy=true"},
+            provider = "org.apache.openejb.jpa.JPAHasBeanManagerTest$
TheTestProvider")
+    public static class Dao {
+        @PersistenceContext
+        private EntityManager em;
+        private TheTestEntity persisted;
+
+        public void start(@Observes @Initialized(ApplicationScoped.class)
final Object boot) {
+            TheTestEntity entity = new TheTestEntity();
+            em.persist(entity); // ensure it works
+            persisted = entity;
+        }
+
+        public void doAsserts() {
+            assertNotNull(TheTestProvider.MAP);
+            final Object bm = TheTestProvider.MAP.get("
javax.persistence.bean.manager");
+            assertNotNull(bm);
+            assertTrue(BeanManager.class.isInstance(bm));
+            assertNotNull(em.find(TheTestEntity.class, persisted.getId()));
+        }
+    }
+
+    @Startup
+    @Singleton
+    public static class EJBDao {
+        @PersistenceContext
+        private EntityManager em;
+
+        @PostConstruct
+        public void start() {
+            TheTestEntity entity = new TheTestEntity();
+            em.persist(entity); // ensure it works
+        }
+    }
+
+    public static class TheTestProvider extends PersistenceProviderImpl {
+        private static Map MAP;
+
+        @Override
+        public OpenJPAEntityManagerFactory
createContainerEntityManagerFactory(final
PersistenceUnitInfo pui, final Map m) {
+            MAP = m;
+            // only works cause of lazy property
+            final BeanManager beanManager = BeanManager.class.cast(m.get("
javax.persistence.bean.manager"));
+            assertNotNull(beanManager.getReference(beanManager.
resolve(beanManager.getBeans(Dao.class)), Dao.class, null));
+            // just delegate to openjpa since we don't aim at
reimplementing JPA in a test ;)
+            return super.createContainerEntityManagerFactory(pui, m);
+        }
+    }
+
+    @Entity
+    public static class TheTestEntity {
+        @Id
+        @GeneratedValue
+        private long id;
+
+        public long getId() {
+            return id;
+        }
+    }
+}

Reply via email to