You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by cs...@apache.org on 2017/04/18 12:55:01 UTC

[09/50] aries-jpa git commit: [ARIES-1558] JPA support for CDI

[ARIES-1558] JPA support for CDI

git-svn-id: https://svn.apache.org/repos/asf/aries/trunk/jpa@1748153 13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/aries-jpa/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-jpa/commit/ad5990d4
Tree: http://git-wip-us.apache.org/repos/asf/aries-jpa/tree/ad5990d4
Diff: http://git-wip-us.apache.org/repos/asf/aries-jpa/diff/ad5990d4

Branch: refs/heads/master
Commit: ad5990d4a1fcb211f0e1fe2e764770d4086e4fe2
Parents: c52145d
Author: gnodet <gn...@13f79535-47bb-0310-9956-ffa450edef68>
Authored: Mon Jun 13 09:27:47 2016 +0000
Committer: gnodet <gn...@13f79535-47bb-0310-9956-ffa450edef68>
Committed: Mon Jun 13 09:27:47 2016 +0000

----------------------------------------------------------------------
 examples/pom.xml                                |   1 +
 examples/tasklist-cdi/osgi.bnd                  |   4 +
 examples/tasklist-cdi/pom.xml                   |  87 ++++++
 .../tasklist/cdi/impl/TaskServiceImpl.java      |  67 +++++
 .../tasklist/cdi/impl/TasklistServlet.java      | 104 +++++++
 .../src/main/resources/META-INF/beans.xml       |   0
 .../tasklist/cdi/impl/TaskServiceImplTest.java  |  65 +++++
 .../src/test/resources/META-INF/persistence.xml |  33 +++
 jpa-cdi/osgi.bnd                                |  11 +
 jpa-cdi/pom.xml                                 |  87 ++++++
 .../aries/jpa/cdi/EntityManagerProducer.java    |  52 ++++
 .../org/apache/aries/jpa/cdi/JpaExtension.java  |  60 ++++
 .../aries/jpa/cdi/PersistenceAnnotatedType.java | 141 ++++++++++
 .../aries/jpa/cdi/TransactionExtension.java     |  73 +++++
 .../aries/jpa/cdi/TransactionSupport.java       |  44 +++
 .../aries/jpa/cdi/TransactionalContext.java     | 277 +++++++++++++++++++
 .../aries/jpa/cdi/TransactionalInterceptor.java | 226 +++++++++++++++
 .../aries/jpa/cdi/support/FilterLiteral.java    |  35 +++
 .../cdi/support/ForwardingAnnotatedField.java   |  73 +++++
 .../cdi/support/ForwardingAnnotatedType.java    |  79 ++++++
 .../aries/jpa/cdi/support/InjectLiteral.java    |  26 ++
 .../aries/jpa/cdi/support/ServiceLiteral.java   |  27 ++
 .../aries/jpa/cdi/support/SimpleBean.java       | 101 +++++++
 .../cdi/support/SyntheticAnnotatedField.java    |  65 +++++
 .../aries/jpa/cdi/support/UniqueIdentifier.java |  36 +++
 .../cdi/support/UniqueIdentifierLitteral.java   |  38 +++
 jpa-cdi/src/main/resources/META-INF/beans.xml   |   5 +
 .../javax.enterprise.inject.spi.Extension       |   2 +
 jpa-parent/pom.xml                              |  25 ++
 pom.xml                                         |   1 +
 30 files changed, 1845 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/examples/pom.xml
----------------------------------------------------------------------
diff --git a/examples/pom.xml b/examples/pom.xml
index 486338d..0cf3b90 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -124,6 +124,7 @@
         <module>tasklist-blueprint</module>
         <module>tasklist-ds</module>
         <module>tasklist-model</module>
+        <module>tasklist-cdi</module>
     </modules>
 
 </project>

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/examples/tasklist-cdi/osgi.bnd
----------------------------------------------------------------------
diff --git a/examples/tasklist-cdi/osgi.bnd b/examples/tasklist-cdi/osgi.bnd
new file mode 100644
index 0000000..1c76259
--- /dev/null
+++ b/examples/tasklist-cdi/osgi.bnd
@@ -0,0 +1,4 @@
+Require-Capability: \
+    osgi.extender; filter:="(osgi.extender=pax.cdi)", \
+        org.ops4j.pax.cdi.extension; filter:="(extension=pax-cdi-extension2)", \
+        org.ops4j.pax.cdi.extension; filter:="(extension=aries-jpa-cdi)",

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/examples/tasklist-cdi/pom.xml
----------------------------------------------------------------------
diff --git a/examples/tasklist-cdi/pom.xml b/examples/tasklist-cdi/pom.xml
new file mode 100644
index 0000000..f184d1d
--- /dev/null
+++ b/examples/tasklist-cdi/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.aries.jpa.example</groupId>
+        <artifactId>org.apache.aries.jpa.example.parent</artifactId>
+        <version>2.4.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <artifactId>org.apache.aries.jpa.example.tasklist.cdi</artifactId>
+    <name>Apache Aries JPA example tasklist cdi</name>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <baseline.skip>true</baseline.skip>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>javax.persistence</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.transaction</groupId>
+            <artifactId>javax.transaction-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.jpa.example</groupId>
+            <artifactId>org.apache.aries.jpa.example.tasklist.model</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ops4j.pax.cdi</groupId>
+            <artifactId>pax-cdi-api</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+            <version>1</version>
+        </dependency>
+
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-entitymanager</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.derby</groupId>
+            <artifactId>derby</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.enterprise</groupId>
+            <artifactId>cdi-api</artifactId>
+            <version>1.2</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/examples/tasklist-cdi/src/main/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TaskServiceImpl.java
----------------------------------------------------------------------
diff --git a/examples/tasklist-cdi/src/main/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TaskServiceImpl.java b/examples/tasklist-cdi/src/main/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TaskServiceImpl.java
new file mode 100644
index 0000000..cab337d
--- /dev/null
+++ b/examples/tasklist-cdi/src/main/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TaskServiceImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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 WARRANTIESOR 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.aries.jpa.example.tasklist.cdi.impl;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.transaction.Transactional;
+import javax.transaction.Transactional.TxType;
+import java.util.Collection;
+
+import org.apache.aries.jpa.example.tasklist.model.Task;
+import org.apache.aries.jpa.example.tasklist.model.TaskService;
+
+@Transactional
+public class TaskServiceImpl implements TaskService {
+
+    @PersistenceContext(unitName = "tasklist")
+    EntityManager em;
+
+    @Transactional(TxType.SUPPORTS)
+    @Override
+    public Task getTask(Integer id) {
+        return em.find(Task.class, id);
+    }
+
+    
+    @Override
+    public void addTask(Task task) {
+        em.persist(task);
+        em.flush();
+    }
+
+    @Transactional(TxType.SUPPORTS)
+    @Override
+    public Collection<Task> getTasks() {
+        CriteriaQuery<Task> query = em.getCriteriaBuilder().createQuery(Task.class);
+        return em.createQuery(query.select(query.from(Task.class))).getResultList();
+    }
+
+    @Override
+    public void updateTask(Task task) {
+        em.persist(task);
+    }
+
+    @Override
+    public void deleteTask(Integer id) {
+        em.remove(getTask(id));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/examples/tasklist-cdi/src/main/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TasklistServlet.java
----------------------------------------------------------------------
diff --git a/examples/tasklist-cdi/src/main/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TasklistServlet.java b/examples/tasklist-cdi/src/main/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TasklistServlet.java
new file mode 100644
index 0000000..1f1f14e
--- /dev/null
+++ b/examples/tasklist-cdi/src/main/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TasklistServlet.java
@@ -0,0 +1,104 @@
+/*
+ * 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 WARRANTIESOR 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.aries.jpa.example.tasklist.cdi.impl;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.aries.jpa.example.tasklist.model.Task;
+import org.apache.aries.jpa.example.tasklist.model.TaskService;
+import org.ops4j.pax.cdi.api2.Component;
+import org.ops4j.pax.cdi.api2.Contract;
+import org.ops4j.pax.cdi.api2.Immediate;
+import org.ops4j.pax.cdi.api2.Properties;
+import org.ops4j.pax.cdi.api2.Property;
+import org.ops4j.pax.cdi.api2.Service;
+
+@Component @Service @Immediate
+@Contract(Servlet.class)
+@Properties(@Property(name = "alias", value="/tasklist"))
+public class TasklistServlet extends HttpServlet {
+
+    private static final long serialVersionUID = 34992072289535683L;
+
+    @Inject
+    private transient TaskService taskService;
+
+    @PostConstruct
+    void initialize() {
+
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
+        IOException {
+        String add = req.getParameter("add");
+        String taskId = req.getParameter("taskId");
+        String title = req.getParameter("title");
+        PrintWriter writer = resp.getWriter(); // NOSONAR
+        if (add != null) {
+            addTask(taskId, title);
+        } else if (taskId != null && taskId.length() > 0) {
+            showTask(writer, taskId);
+        } else {
+            showTaskList(writer);
+        }
+    }
+
+    private void addTask(String taskId, String title) {
+        Task task = new Task();
+        task.setId(new Integer(taskId));
+        task.setTitle(title);
+        taskService.addTask(task );
+    }
+
+    private void showTaskList(PrintWriter writer) {
+        writer.println("<h1>Tasks</h1>");
+        Collection<Task> tasks = taskService.getTasks();
+        for (Task task : tasks) {
+            writer.println("<a href=\"?taskId=" + task.getId() + "\">" + task.getTitle() + "</a><BR/>");
+        }
+    }
+
+    private void showTask(PrintWriter writer, String taskId) {
+        SimpleDateFormat sdf = new SimpleDateFormat();
+        Task task = taskService.getTask(new Integer(taskId));
+        if (task != null) {
+            writer.println("<h1>Task " + task.getTitle() + " </h1>");
+            if (task.getDueDate() != null) {
+                writer.println("Due date: " + sdf.format(task.getDueDate()) + "<br/>");
+            }
+            writer.println(task.getDescription());
+        } else {
+            writer.println("Task with id " + taskId + " not found");
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/examples/tasklist-cdi/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/examples/tasklist-cdi/src/main/resources/META-INF/beans.xml b/examples/tasklist-cdi/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/examples/tasklist-cdi/src/test/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TaskServiceImplTest.java
----------------------------------------------------------------------
diff --git a/examples/tasklist-cdi/src/test/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TaskServiceImplTest.java b/examples/tasklist-cdi/src/test/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TaskServiceImplTest.java
new file mode 100644
index 0000000..43a53d9
--- /dev/null
+++ b/examples/tasklist-cdi/src/test/java/org/apache/aries/jpa/example/tasklist/cdi/impl/TaskServiceImplTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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 WARRANTIESOR 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.aries.jpa.example.tasklist.cdi.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import org.apache.aries.jpa.example.tasklist.cdi.impl.TaskServiceImpl;
+import org.apache.aries.jpa.example.tasklist.model.Task;
+import org.apache.aries.jpa.example.tasklist.model.TaskService;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TaskServiceImplTest {
+    @Test
+    public void testPersistence() {
+        // Make sure derby.log is in target
+        System.setProperty("derby.stream.error.file", "target/derby.log");
+        TaskServiceImpl taskServiceImpl = new TaskServiceImpl();
+        EntityManagerFactory emf = createTestEMF();
+        final EntityManager em = emf.createEntityManager();
+        em.getTransaction().begin();
+        taskServiceImpl.em = em;
+
+        TaskService taskService = taskServiceImpl;
+
+        Task task = new Task();
+        task.setId(1);
+        task.setTitle("test");
+        taskService.addTask(task);
+
+        Task task2 = taskService.getTask(1);
+        Assert.assertEquals(task.getTitle(), task2.getTitle());
+        em.getTransaction().commit();
+        em.close();
+    }
+
+    private EntityManagerFactory createTestEMF() {
+        Map<String, String> properties = new HashMap<String, String>();
+        properties.put("javax.persistence.jdbc.driver", "org.apache.derby.jdbc.EmbeddedDriver");
+        properties.put("javax.persistence.jdbc.url", "jdbc:derby:memory:TEST;create=true");
+        EntityManagerFactory emf = Persistence.createEntityManagerFactory("tasklist", properties);
+        return emf;
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/examples/tasklist-cdi/src/test/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/examples/tasklist-cdi/src/test/resources/META-INF/persistence.xml b/examples/tasklist-cdi/src/test/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..84b94ec
--- /dev/null
+++ b/examples/tasklist-cdi/src/test/resources/META-INF/persistence.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
+    
+    <persistence-unit name="tasklist" transaction-type="RESOURCE_LOCAL">
+        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
+       	<class>org.apache.aries.jpa.example.tasklist.model.Task</class>
+        <properties>
+            <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect"/>
+            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
+        </properties>
+    </persistence-unit>
+
+</persistence>

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/osgi.bnd
----------------------------------------------------------------------
diff --git a/jpa-cdi/osgi.bnd b/jpa-cdi/osgi.bnd
new file mode 100644
index 0000000..7b9b23f
--- /dev/null
+++ b/jpa-cdi/osgi.bnd
@@ -0,0 +1,11 @@
+Import-Package: \
+    javax.persistence*;version=2.1, \
+    *
+Provide-Capability: \
+    org.ops4j.pax.cdi.extension; extension=aries-jpa-cdi; \
+        version:Version=${version;====;${replace;${project.version};-;.}}
+Require-Capability: \
+    org.ops4j.pax.cdi.extension; filter:="(extension=pax-cdi-extension2)"
+    osgi.extender; filter:="(osgi.extender=aries.jpa)"
+
+

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/pom.xml
----------------------------------------------------------------------
diff --git a/jpa-cdi/pom.xml b/jpa-cdi/pom.xml
new file mode 100644
index 0000000..fc69007
--- /dev/null
+++ b/jpa-cdi/pom.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.aries.jpa</groupId>
+        <artifactId>org.apache.aries.jpa.parent</artifactId>
+        <version>2.4.0-SNAPSHOT</version>
+        <relativePath>../jpa-parent</relativePath>
+    </parent>
+    <artifactId>org.apache.aries.jpa.cdi</artifactId>
+    <name>Apache Aries JPA cdi</name>
+    <description>CDI integration for injecting EntityManager, EntityManagerFactory and EmSupplier.</description>
+    <packaging>bundle</packaging>
+
+    <properties>
+        <baseline.skip>true</baseline.skip>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jpa_2.0_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jta_1.2_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jcdi_1.1_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-atinject_1.0_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-interceptor_1.2_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-annotation_1.2_spec</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.ops4j.pax.cdi</groupId>
+            <artifactId>pax-cdi-extension2</artifactId>
+            <version>1.0.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.jpa</groupId>
+            <artifactId>org.apache.aries.jpa.api</artifactId>
+            <version>2.4.0-SNAPSHOT</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/EntityManagerProducer.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/EntityManagerProducer.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/EntityManagerProducer.java
new file mode 100644
index 0000000..5cdf0a5
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/EntityManagerProducer.java
@@ -0,0 +1,52 @@
+/*
+ * 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.aries.jpa.cdi;
+
+import javax.persistence.EntityManager;
+import java.lang.reflect.Proxy;
+
+import org.apache.aries.jpa.template.JpaTemplate;
+import org.apache.aries.jpa.template.TransactionType;
+
+public class EntityManagerProducer {
+
+    public static EntityManager create(JpaTemplate template) {
+        return (EntityManager) Proxy.newProxyInstance(EntityManager.class.getClassLoader(),
+                new Class<?>[]{EntityManager.class},
+                (proxy, method, args) -> {
+                    try {
+                        return template.txExpr(TransactionType.Supports, em -> {
+                            try {
+                                return method.invoke(em, args);
+                            } catch (RuntimeException e) {
+                                throw e;
+                            } catch (Exception e) {
+                                throw new RuntimeException(e);
+                            }
+                        });
+                    } catch (RuntimeException e) {
+                        if (e.getClass() == RuntimeException.class
+                                && e.getCause() != null
+                                && e.getCause().toString().equals(e.getMessage())) {
+                            throw e.getCause();
+                        }
+                        throw e;
+                    }
+                });
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/JpaExtension.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/JpaExtension.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/JpaExtension.java
new file mode 100644
index 0000000..0c2c6f6
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/JpaExtension.java
@@ -0,0 +1,60 @@
+/*
+ * 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.aries.jpa.cdi;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceUnit;
+import java.util.ArrayList;
+import java.util.List;
+
+@ApplicationScoped
+public class JpaExtension implements Extension {
+
+    List<Bean<?>> beans = new ArrayList<Bean<?>>();
+
+    public <T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> event, BeanManager manager) {
+        boolean hasPersistenceField = false;
+        for (AnnotatedField<? super T> field : event.getAnnotatedType().getFields()) {
+            if (field.isAnnotationPresent(PersistenceContext.class)
+                    || field.isAnnotationPresent(PersistenceUnit.class)) {
+                hasPersistenceField = true;
+                break;
+            }
+        }
+        if (hasPersistenceField) {
+            PersistenceAnnotatedType<T> pat = new PersistenceAnnotatedType<T>(manager, event.getAnnotatedType());
+            beans.addAll(pat.getProducers());
+            event.setAnnotatedType(pat);
+        }
+    }
+
+    public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager) {
+        for (Bean<?> bean : beans) {
+            event.addBean(bean);
+        }
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/PersistenceAnnotatedType.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/PersistenceAnnotatedType.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/PersistenceAnnotatedType.java
new file mode 100644
index 0000000..13ac947
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/PersistenceAnnotatedType.java
@@ -0,0 +1,141 @@
+/*
+ * 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.aries.jpa.cdi;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceUnit;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.aries.jpa.cdi.support.FilterLiteral;
+import org.apache.aries.jpa.cdi.support.ForwardingAnnotatedType;
+import org.apache.aries.jpa.cdi.support.InjectLiteral;
+import org.apache.aries.jpa.cdi.support.ServiceLiteral;
+import org.apache.aries.jpa.cdi.support.SimpleBean;
+import org.apache.aries.jpa.cdi.support.SyntheticAnnotatedField;
+import org.apache.aries.jpa.cdi.support.UniqueIdentifier;
+import org.apache.aries.jpa.cdi.support.UniqueIdentifierLitteral;
+import org.apache.aries.jpa.template.JpaTemplate;
+import org.ops4j.pax.cdi.extension2.api.OsgiExtension;
+
+import static java.util.Collections.unmodifiableSet;
+
+public class PersistenceAnnotatedType<T> extends ForwardingAnnotatedType<T> {
+
+    private final BeanManager manager;
+    private final Set<AnnotatedField<? super T>> fields;
+    private final List<Bean<?>> beans = new ArrayList<>();
+
+    public PersistenceAnnotatedType(BeanManager manager, AnnotatedType<T> delegate) {
+        super(delegate);
+        this.manager = manager;
+        this.fields = new HashSet<>();
+        for (AnnotatedField<? super T> field : delegate.getFields()) {
+            if (field.isAnnotationPresent(PersistenceContext.class)) {
+                field = decorateContext(field);
+            } else if (field.isAnnotationPresent(PersistenceUnit.class)) {
+                field = decorateUnit(field);
+            }
+            this.fields.add(field);
+        }
+    }
+
+    private boolean hasUnitName(PersistenceContext pc) {
+        return !pc.unitName().isEmpty();
+    }
+
+    private boolean hasUnitName(PersistenceUnit pu) {
+        return !pu.unitName().isEmpty();
+    }
+
+    private <X> AnnotatedField<X> decorateContext(AnnotatedField<X> field) {
+        final PersistenceContext persistenceContext = field.getAnnotation(PersistenceContext.class);
+        final UniqueIdentifier identifier = UniqueIdentifierLitteral.random();
+
+        Set<Annotation> templateQualifiers = new HashSet<>();
+        templateQualifiers.add(ServiceLiteral.SERVICE);
+        if (hasUnitName(persistenceContext)) {
+            templateQualifiers.add(new FilterLiteral("(osgi.unit.name=" + persistenceContext.unitName() + ")"));
+        }
+        Bean<JpaTemplate> bean = manager.getExtension(OsgiExtension.class)
+                .globalDependency(JpaTemplate.class, templateQualifiers);
+
+        Set<Annotation> qualifiers = new HashSet<>();
+        qualifiers.add(identifier);
+        Bean<EntityManager> b = new SimpleBean<>(EntityManager.class, Dependent.class, Collections.singleton(EntityManager.class), qualifiers, () -> {
+            CreationalContext<JpaTemplate> context = manager.createCreationalContext(bean);
+            JpaTemplate template = (JpaTemplate) manager.getReference(bean, JpaTemplate.class, context);
+            return EntityManagerProducer.create(template);
+        });
+        beans.add(b);
+
+        Set<Annotation> fieldAnnotations = new HashSet<>();
+        fieldAnnotations.add(InjectLiteral.INJECT);
+        fieldAnnotations.add(identifier);
+        return new SyntheticAnnotatedField<>(field, fieldAnnotations);
+    }
+
+    private <X> AnnotatedField<X> decorateUnit(AnnotatedField<X> field) {
+        final PersistenceUnit persistenceUnit = field.getAnnotation(PersistenceUnit.class);
+        final UniqueIdentifier identifier = UniqueIdentifierLitteral.random();
+
+        Set<Annotation> templateQualifiers = new HashSet<>();
+        templateQualifiers.add(ServiceLiteral.SERVICE);
+        if (hasUnitName(persistenceUnit)) {
+            templateQualifiers.add(new FilterLiteral("(osgi.unit.name=" + persistenceUnit.unitName() + ")"));
+        }
+        Bean<EntityManagerFactory> bean = manager.getExtension(OsgiExtension.class)
+                .globalDependency(EntityManagerFactory.class, templateQualifiers);
+
+        Set<Annotation> qualifiers = new HashSet<>();
+        qualifiers.add(identifier);
+        Bean<EntityManagerFactory> b = new SimpleBean<>(EntityManagerFactory.class, Dependent.class, Collections.singleton(EntityManagerFactory.class), qualifiers, () -> {
+            CreationalContext<EntityManagerFactory> context = manager.createCreationalContext(bean);
+            return (EntityManagerFactory) manager.getReference(bean, EntityManagerFactory.class, context);
+        });
+        beans.add(b);
+
+        Set<Annotation> fieldAnnotations = new HashSet<>();
+        fieldAnnotations.add(InjectLiteral.INJECT);
+        fieldAnnotations.add(identifier);
+        return new SyntheticAnnotatedField<>(field, fieldAnnotations);
+    }
+
+    @Override
+    public Set<AnnotatedField<? super T>> getFields() {
+        return unmodifiableSet(fields);
+    }
+
+    public Collection<? extends Bean<?>> getProducers() {
+        return beans;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionExtension.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionExtension.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionExtension.java
new file mode 100644
index 0000000..9968488
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionExtension.java
@@ -0,0 +1,73 @@
+/*
+ * 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.aries.jpa.cdi;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessManagedBean;
+import javax.transaction.Transactional;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+@ApplicationScoped
+public class TransactionExtension implements Extension {
+
+    private Map<Method, Transactional> transactionAttributes;
+
+    public TransactionExtension() {
+        transactionAttributes = new HashMap<>();
+    }
+
+    <X> void processBean(@Observes ProcessManagedBean<X> event) {
+        AnnotatedType<X> annotatedType = event.getAnnotatedBeanClass();
+        Transactional classTx = annotatedType.getAnnotation(Transactional.class);
+        for (AnnotatedMethod<? super X> am : annotatedType.getMethods()) {
+            Transactional methodTx = am.getAnnotation(Transactional.class);
+            if (classTx != null || methodTx != null) {
+                Method method = am.getJavaMember();
+                Transactional attrType = mergeTransactionAttributes(classTx, methodTx);
+                transactionAttributes.put(method, attrType);
+            }
+        }
+    }
+
+    void beforeBeanDiscovery(@Observes BeforeBeanDiscovery event, BeanManager manager) {
+        event.addAnnotatedType(manager.createAnnotatedType(TransactionSupport.class));
+        event.addAnnotatedType(manager.createAnnotatedType(TransactionalInterceptor.class));
+        event.addInterceptorBinding(Transactional.class);
+    }
+
+    void afterBeanDiscovered(@Observes AfterBeanDiscovery event, BeanManager beanManager) {
+        event.addContext(new TransactionalContext(beanManager));
+    }
+
+    private Transactional mergeTransactionAttributes(Transactional classAttribute, Transactional methodAttribute) {
+        return methodAttribute != null ? methodAttribute : classAttribute;
+    }
+
+    Transactional getTransactionAttribute(Method method) {
+        return transactionAttributes.get(method);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionSupport.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionSupport.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionSupport.java
new file mode 100644
index 0000000..2acb356
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionSupport.java
@@ -0,0 +1,44 @@
+/*
+ * 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.aries.jpa.cdi;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+
+import org.ops4j.pax.cdi.api2.Global;
+import org.ops4j.pax.cdi.api2.Service;
+
+@ApplicationScoped
+public class TransactionSupport {
+
+    @Inject @Global @Service
+    private TransactionManager transactionManager;
+
+    @Inject @Global @Service
+    private TransactionSynchronizationRegistry transactionSynchronizationRegistry;
+
+    public TransactionManager getTransactionManager() {
+        return transactionManager;
+    }
+
+    public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() {
+        return transactionSynchronizationRegistry;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionalContext.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionalContext.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionalContext.java
new file mode 100644
index 0000000..ce0c031
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionalContext.java
@@ -0,0 +1,277 @@
+/*
+ * 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.aries.jpa.cdi;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionScoped;
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TransactionalContext implements Context {
+
+    private static final Object TRANSACTION_BEANS_KEY = TransactionalContext.class.getName() + ".TRANSACTION_BEANS";
+
+    private static final Logger log = LoggerFactory.getLogger(TransactionalContext.class);
+
+    private BeanManager beanManager;
+
+    private volatile TransactionSupport transactionSupport;
+
+    /**
+     * Creates a new transactional context.
+     *
+     * @param beanManager {@link BeanManager}.
+     */
+    TransactionalContext(BeanManager beanManager) {
+        this.beanManager = beanManager;
+    }
+
+    /**
+     * Obtains a reference to a {@link TransactionSupport} bean.
+     *
+     * @return a bean that implements {@link TransactionSupport}.
+     */
+    private TransactionSupport getTransactionSupportReference() {
+        @SuppressWarnings("unchecked")
+        Bean<TransactionSupport> bean = (Bean<TransactionSupport>) beanManager
+                .resolve(beanManager.getBeans(TransactionSupport.class));
+        if (bean == null) {
+            throw new RuntimeException("TransactionSupport was not found");
+        }
+
+        CreationalContext<TransactionSupport> ctx = beanManager.createCreationalContext(bean);
+        return (TransactionSupport) beanManager.getReference(bean,
+                TransactionSupport.class, ctx);
+    }
+
+    /**
+     * Lazily initialize the object field and gets a reference to a bean that
+     * implements {@link TransactionSupport}.
+     *
+     * @return a bean that implements {@link TransactionSupport}.
+     */
+    private TransactionSupport getTransactionSupport() {
+        if (transactionSupport == null) {
+            synchronized (this) {
+                if (transactionSupport == null) {
+                    transactionSupport = getTransactionSupportReference();
+                }
+            }
+        }
+
+        return transactionSupport;
+    }
+
+    /**
+     * Registers a synchronization object for the current transaction.
+     *
+     * @param transactionSupport a {@link TransactionSupport} bean.
+     * @param instances          a map that contains transaction scoped beans for the
+     *                           current transaction.
+     */
+    private <T> void registerSynchronization(
+            TransactionSupport transactionSupport,
+            Map<Contextual<T>, ContextualInstance<T>> instances) {
+        transactionSupport.getTransactionSynchronizationRegistry()
+                .registerInterposedSynchronization(new TransactionSynchronization<T>(instances));
+    }
+
+    /**
+     * Retrieves the map that contains transaction scoped beans for the current
+     * transaction.
+     *
+     * @param transactionSupport a bean that implements {@link TransactionSupport}.
+     * @return instances of transaction scoped beans for the current
+     * transaction.
+     */
+    private <T> Map<Contextual<T>, ContextualInstance<T>> getInstances(
+            TransactionSupport transactionSupport) {
+        @SuppressWarnings("unchecked")
+        Map<Contextual<T>, ContextualInstance<T>> instances =
+                (Map<Contextual<T>, ContextualInstance<T>>) transactionSupport.getTransactionSynchronizationRegistry()
+                        .getResource(TRANSACTION_BEANS_KEY);
+        if (instances == null) {
+            instances = new HashMap<Contextual<T>, ContextualInstance<T>>();
+            transactionSupport
+                    .getTransactionSynchronizationRegistry()
+                    .putResource(TRANSACTION_BEANS_KEY, instances);
+
+            registerSynchronization(transactionSupport, instances);
+        }
+
+        return instances;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <T> T get(
+            Contextual<T> contextual) {
+        return get(contextual, null);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <T> T get(
+            Contextual<T> contextual,
+            CreationalContext<T> creationalContext) {
+        if (!isActive()) {
+            throw new ContextNotActiveException();
+        }
+
+        if (contextual == null) {
+            throw new IllegalArgumentException(
+                    "No contextual specified to retrieve");
+        }
+
+        TransactionSupport transactionSupport = getTransactionSupport();
+        Map<Contextual<T>, ContextualInstance<T>> instances =
+                getInstances(transactionSupport);
+        ContextualInstance<T> contextualInstance = instances.get(contextual);
+        if (contextualInstance != null) {
+            return contextualInstance.instance;
+        } else if (creationalContext == null) {
+            return null;
+        } else {
+            T instance = contextual.create(creationalContext);
+            contextualInstance = new ContextualInstance<T>(instance,
+                    creationalContext);
+            instances.put(contextual, contextualInstance);
+
+            if (log.isDebugEnabled()) {
+                log.debug("Created a new transaction scoped instance "
+                        + contextualInstance);
+            }
+
+            return instance;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Class<? extends Annotation> getScope() {
+        return TransactionScoped.class;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean isActive() {
+        try {
+            return getTransactionSupport().getTransactionManager().getStatus() == Status.STATUS_ACTIVE;
+        } catch (SystemException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * <p>
+     * Synchronization object that destroys transaction scoped beans after the
+     * transaction ends.
+     * </p>
+     *
+     * @author Vlad Arkhipov
+     */
+    private static class TransactionSynchronization<T>
+            implements Synchronization {
+        private Map<Contextual<T>, ContextualInstance<T>> instances;
+
+        /**
+         * Creates a new synchronization.
+         *
+         * @param instances instances of transaction scoped beans for the
+         *                  current transaction.
+         */
+        TransactionSynchronization(
+                Map<Contextual<T>, ContextualInstance<T>> instances) {
+            this.instances = instances;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void beforeCompletion() {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void afterCompletion(
+                int status) {
+            for (Map.Entry<Contextual<T>, ContextualInstance<T>> entry : instances.entrySet()) {
+                entry.getValue().destroy(entry.getKey());
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * An object that represents an instance of a bean. Contains a reference for
+     * a bean and {@link CreationalContext}.
+     * </p>
+     *
+     * @author Vlad Arkhipov
+     */
+    private static class ContextualInstance<T> {
+        private T instance;
+
+        private CreationalContext<T> creationalContext;
+
+        /**
+         * Creates a new object that represents an instance of a bean.
+         *
+         * @param instance          an instance of a bean.
+         * @param creationalContext a {@link CreationalContext}.
+         */
+        public ContextualInstance(
+                T instance,
+                CreationalContext<T> creationalContext) {
+            this.instance = instance;
+            this.creationalContext = creationalContext;
+        }
+
+        /**
+         * Destroys the bean.
+         *
+         * @param contextual a {@link Contextual}.
+         */
+        void destroy(
+                Contextual<T> contextual) {
+            if (log.isDebugEnabled()) {
+                log.debug("Destroying transaction scoped bean instance "
+                        + this);
+            }
+
+            contextual.destroy(instance, creationalContext);
+            creationalContext.release();
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionalInterceptor.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionalInterceptor.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionalInterceptor.java
new file mode 100644
index 0000000..f935ca1
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/TransactionalInterceptor.java
@@ -0,0 +1,226 @@
+/*
+ * 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.aries.jpa.cdi;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.Transactional;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Transactional
+@Interceptor
+@Priority(Interceptor.Priority.PLATFORM_BEFORE + 200)
+class TransactionalInterceptor {
+
+    private static final Logger log = LoggerFactory.getLogger(TransactionalInterceptor.class);
+
+    @Inject
+    private BeanManager beanManager;
+
+    @Inject
+    private TransactionSupport transactionSupport;
+
+    @AroundInvoke
+    Object aroundInvoke(InvocationContext invocationContext) throws Exception {
+
+        TransactionManager transactionManager = transactionSupport.getTransactionManager();
+        boolean active = isTransactionActive(transactionManager);
+        TransactionExtension extension = beanManager.getExtension(TransactionExtension.class);
+        Transactional attr = extension.getTransactionAttribute(invocationContext.getMethod());
+        Boolean requiresNew = requiresNew(active, attr.value());
+
+        boolean debug = log.isDebugEnabled();
+
+        if (debug) {
+            log.debug("Invoking transactional method {}, attr = {}, active = {}, requiresNew = {}",
+                    invocationContext.getMethod(), attr.value(), active, requiresNew);
+        }
+
+        // Suspend the current transaction if transaction attribute is // REQUIRES_NEW or NOT_SUPPORTED.
+        Transaction previous = null;
+        if ((requiresNew != Boolean.FALSE) && active) {
+            if (debug) {
+                log.debug("Suspending the current transaction");
+            }
+            previous = transactionManager.suspend();
+        }
+
+        try {
+            if (requiresNew == Boolean.TRUE) {
+                if (debug) {
+                    log.debug("Starting a new transaction");
+                }
+                transactionManager.begin();
+            }
+
+            Object result;
+            try {
+                result = invocationContext.proceed();
+            } catch (Exception e) {
+                if (requiresNew == Boolean.FALSE) {
+                    if (needsRollback(attr, e)) {
+                        transactionManager.setRollbackOnly();
+                    }
+                } else if (requiresNew == Boolean.TRUE) {
+                    if (needsRollback(attr, e)) {
+                        if (debug) {
+                            log.debug("Rolling back the current transaction");
+                        }
+                        transactionManager.rollback();
+                    } else {
+                        if (debug) {
+                            log.debug("Committing the current transaction");
+                        }
+                        transactionManager.commit();
+                    }
+                }
+
+                throw e;
+            }
+
+            if (requiresNew == Boolean.TRUE) {
+                if (transactionManager.getStatus() == Status.STATUS_MARKED_ROLLBACK) {
+                    if (debug) {
+                        log.debug("Rolling back the current transaction");
+                    }
+                    transactionManager.rollback();
+                } else {
+                    if (debug) {
+                        log.debug("Committing the current transaction");
+                    }
+                    transactionManager.commit();
+                }
+            }
+
+            return result;
+        } finally {
+            // Resume the previous transaction if it was suspended.
+            if (previous != null) {
+                if (debug) {
+                    log.debug("Resuming the previous transaction");
+                }
+                transactionManager.resume(previous);
+            }
+        }
+    }
+
+    /**
+     * Checks if the current transaction is active, rolled back or marked for
+     * rollback.
+     *
+     * @return {@code true} if the current transaction is active, rolled back or
+     * marked for rollback, {@code false} otherwise.
+     * @throws SystemException thrown if the transaction manager encounters an
+     *                         unexpected error condition
+     */
+    private boolean isTransactionActive(TransactionManager transactionManager) throws SystemException {
+        switch (transactionManager.getStatus()) {
+            case Status.STATUS_ACTIVE:
+            case Status.STATUS_MARKED_ROLLBACK:
+            case Status.STATUS_ROLLEDBACK:
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Determines whether it is necessary to begin a new transaction.
+     *
+     * @param active    the status of the current transaction.
+     * @param attribute the transaction attribute of the current method.
+     * @return {@code Boolean.TRUE} if the interceptor should suspend the
+     * current transaction and invoke the method within a new
+     * transaction, {@code Boolean.FALSE} if the interceptor should
+     * invoke the method within the current transaction, {@code null} if
+     * the interceptor should suspend the current transaction and invoke
+     * the method outside of transaction.
+     */
+    private Boolean requiresNew(boolean active, Transactional.TxType attribute) {
+        switch (attribute) {
+            case MANDATORY:
+                if (active) {
+                    return false;
+                } else {
+                    throw new IllegalStateException("Transaction is required to perform this method");
+                }
+
+            case NEVER:
+                if (!active) {
+                    return null;
+                } else {
+                    throw new IllegalStateException("This method cannot be invoked within a transaction");
+                }
+
+            case NOT_SUPPORTED:
+                return null;
+
+            case REQUIRED:
+                return !active;
+
+            case REQUIRES_NEW:
+                return true;
+
+            case SUPPORTS:
+                if (active) {
+                    return false;
+                } else {
+                    return null;
+                }
+
+            default:
+                throw new UnsupportedOperationException("Unsupported TransactionAttribute value " + attribute);
+        }
+    }
+
+    /**
+     * Determines whether it is necessary to rollback the current transaction
+     * when the specified exception occurred during the method invocation.
+     *
+     *
+     * @param attr
+     * @param exception the exception that occurred during the method
+     *                  invocation.
+     * @return {@code true} if the interceptor should rollback the current
+     * transaction, {@code false} if the interceptor should commit the
+     * current transaction.
+     */
+    private boolean needsRollback(Transactional attr, Exception exception) {
+        for (Class cl : attr.dontRollbackOn()) {
+            if (cl.isInstance(exception)) {
+                return false;
+            }
+        }
+        for (Class cl : attr.rollbackOn()) {
+            if (cl.isInstance(exception)) {
+                return true;
+            }
+        }
+        return exception instanceof RuntimeException;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/FilterLiteral.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/FilterLiteral.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/FilterLiteral.java
new file mode 100644
index 0000000..f52e1fd
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/FilterLiteral.java
@@ -0,0 +1,35 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.enterprise.util.AnnotationLiteral;
+
+import org.ops4j.pax.cdi.api2.Filter;
+
+public final class FilterLiteral extends AnnotationLiteral<Filter> implements Filter {
+
+    private final String filter;
+
+    public FilterLiteral(String filter) {
+        this.filter = filter;
+    }
+
+    @Override
+    public String value() {
+        return filter;
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ForwardingAnnotatedField.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ForwardingAnnotatedField.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ForwardingAnnotatedField.java
new file mode 100644
index 0000000..d332b58
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ForwardingAnnotatedField.java
@@ -0,0 +1,73 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+public class ForwardingAnnotatedField<X> implements AnnotatedField<X> {
+
+    private final AnnotatedField<X> delegate;
+
+    public ForwardingAnnotatedField(AnnotatedField<X> delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public Field getJavaMember() {
+        return delegate.getJavaMember();
+    }
+
+    @Override
+    public boolean isStatic() {
+        return delegate.isStatic();
+    }
+
+    @Override
+    public AnnotatedType<X> getDeclaringType() {
+        return delegate.getDeclaringType();
+    }
+
+    @Override
+    public Type getBaseType() {
+        return delegate.getBaseType();
+    }
+
+    @Override
+    public Set<Type> getTypeClosure() {
+        return delegate.getTypeClosure();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+        return delegate.getAnnotation(annotationType);
+    }
+
+    @Override
+    public Set<Annotation> getAnnotations() {
+        return delegate.getAnnotations();
+    }
+
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        return delegate.isAnnotationPresent(annotationType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ForwardingAnnotatedType.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ForwardingAnnotatedType.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ForwardingAnnotatedType.java
new file mode 100644
index 0000000..6131852
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ForwardingAnnotatedType.java
@@ -0,0 +1,79 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+public class ForwardingAnnotatedType<X> implements AnnotatedType<X> {
+
+    private final AnnotatedType<X> delegate;
+
+    public ForwardingAnnotatedType(AnnotatedType<X> delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public Class<X> getJavaClass() {
+        return delegate.getJavaClass();
+    }
+
+    @Override
+    public Set<AnnotatedConstructor<X>> getConstructors() {
+        return delegate.getConstructors();
+    }
+
+    @Override
+    public Set<AnnotatedMethod<? super X>> getMethods() {
+        return delegate.getMethods();
+    }
+
+    @Override
+    public Set<AnnotatedField<? super X>> getFields() {
+        return delegate.getFields();
+    }
+
+    @Override
+    public Type getBaseType() {
+        return delegate.getBaseType();
+    }
+
+    @Override
+    public Set<Type> getTypeClosure() {
+        return delegate.getTypeClosure();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+        return delegate.getAnnotation(annotationType);
+    }
+
+    @Override
+    public Set<Annotation> getAnnotations() {
+        return delegate.getAnnotations();
+    }
+
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        return delegate.isAnnotationPresent(annotationType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/InjectLiteral.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/InjectLiteral.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/InjectLiteral.java
new file mode 100644
index 0000000..4fcf6d0
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/InjectLiteral.java
@@ -0,0 +1,26 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.enterprise.util.AnnotationLiteral;
+import javax.inject.Inject;
+
+public final class InjectLiteral extends AnnotationLiteral<Inject> implements Inject {
+
+    public static InjectLiteral INJECT = new InjectLiteral();
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ServiceLiteral.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ServiceLiteral.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ServiceLiteral.java
new file mode 100644
index 0000000..154c5af
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/ServiceLiteral.java
@@ -0,0 +1,27 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.enterprise.util.AnnotationLiteral;
+
+import org.ops4j.pax.cdi.api2.Service;
+
+public final class ServiceLiteral extends AnnotationLiteral<Service> implements Service {
+
+    public static final Service SERVICE = new ServiceLiteral();
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/SimpleBean.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/SimpleBean.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/SimpleBean.java
new file mode 100644
index 0000000..6b302cc
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/SimpleBean.java
@@ -0,0 +1,101 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.Set;
+import java.util.function.Supplier;
+
+public class SimpleBean<T> implements Bean<T> {
+
+    private final Class clazz;
+    private final Class<? extends Annotation> scope;
+    private final Supplier<T> supplier;
+    private final Set<Type> types;
+    private final Set<Annotation> qualifiers;
+
+    public SimpleBean(Class clazz, Class<? extends Annotation> scope, InjectionPoint ip, Supplier<T> supplier) {
+        this(clazz, scope, Collections.singleton(ip.getType()), ip.getQualifiers(), supplier);
+    }
+
+    public SimpleBean(Class clazz, Class<? extends Annotation> scope, Set<Type> types, Set<Annotation> qualifiers, Supplier<T> supplier) {
+        this.clazz = clazz;
+        this.scope = scope;
+        this.types = Collections.unmodifiableSet(types);
+        this.qualifiers = Collections.unmodifiableSet(qualifiers);
+        this.supplier = supplier;
+    }
+
+    @Override
+    public Class<?> getBeanClass() {
+        return clazz;
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isNullable() {
+        return false;
+    }
+
+    @Override
+    public Set<Type> getTypes() {
+        return types;
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers() {
+        return qualifiers;
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope() {
+        return scope;
+    }
+
+    @Override
+    public String getName() {
+        return null;
+    }
+
+    @Override
+    public Set<Class<? extends Annotation>> getStereotypes() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isAlternative() {
+        return false;
+    }
+
+    @Override
+    public T create(CreationalContext<T> creationalContext) {
+        return supplier.get();
+    }
+
+    @Override
+    public void destroy(T instance, CreationalContext<T> creationalContext) {
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/SyntheticAnnotatedField.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/SyntheticAnnotatedField.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/SyntheticAnnotatedField.java
new file mode 100644
index 0000000..092a008
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/SyntheticAnnotatedField.java
@@ -0,0 +1,65 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.enterprise.inject.spi.AnnotatedField;
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class SyntheticAnnotatedField<X> extends ForwardingAnnotatedField<X> {
+
+    private final Map<Class<? extends Annotation>, Annotation> annotations = new HashMap<>();
+
+    public SyntheticAnnotatedField(AnnotatedField<X> delegate) {
+        this(delegate, Collections.<Annotation>emptyList());
+    }
+
+    public SyntheticAnnotatedField(AnnotatedField<X> delegate, Iterable<? extends Annotation> annotations) {
+        super(delegate);
+        for (Annotation annotation : annotations) {
+            addAnnotation(annotation);
+        }
+        for (Annotation annotation : delegate.getAnnotations()) {
+            addAnnotation(annotation);
+        }
+    }
+
+    public void addAnnotation(Annotation annotation) {
+        this.annotations.put(annotation.annotationType(), annotation);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
+        return (T) annotations.get(annotationType);
+    }
+
+    @Override
+    public Set<Annotation> getAnnotations() {
+        return Collections.unmodifiableSet(new HashSet<>(annotations.values()));
+    }
+
+    @Override
+    public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
+        return annotations.containsKey(annotationType);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/UniqueIdentifier.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/UniqueIdentifier.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/UniqueIdentifier.java
new file mode 100644
index 0000000..399e785
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/UniqueIdentifier.java
@@ -0,0 +1,36 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target({METHOD, FIELD, PARAMETER, TYPE})
+@Retention(RUNTIME)
+@Qualifier
+public @interface UniqueIdentifier {
+
+    String id();
+
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/UniqueIdentifierLitteral.java
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/UniqueIdentifierLitteral.java b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/UniqueIdentifierLitteral.java
new file mode 100644
index 0000000..0fb6805
--- /dev/null
+++ b/jpa-cdi/src/main/java/org/apache/aries/jpa/cdi/support/UniqueIdentifierLitteral.java
@@ -0,0 +1,38 @@
+/*
+ * 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.aries.jpa.cdi.support;
+
+import javax.enterprise.util.AnnotationLiteral;
+import java.util.UUID;
+
+public class UniqueIdentifierLitteral extends AnnotationLiteral<UniqueIdentifier> implements UniqueIdentifier {
+
+    private final String id;
+
+    public UniqueIdentifierLitteral(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public String id() {
+        return id;
+    }
+
+    public static UniqueIdentifierLitteral random() {
+        return new UniqueIdentifierLitteral(UUID.randomUUID().toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/resources/META-INF/beans.xml b/jpa-cdi/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..5a535b3
--- /dev/null
+++ b/jpa-cdi/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://java.sun.com/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/jpa-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/jpa-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..f5a449c
--- /dev/null
+++ b/jpa-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1,2 @@
+org.apache.aries.jpa.cdi.TransactionExtension
+org.apache.aries.jpa.cdi.JpaExtension

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/jpa-parent/pom.xml
----------------------------------------------------------------------
diff --git a/jpa-parent/pom.xml b/jpa-parent/pom.xml
index 70574a5..1ea4623 100644
--- a/jpa-parent/pom.xml
+++ b/jpa-parent/pom.xml
@@ -95,6 +95,31 @@
                 <artifactId>geronimo-jta_1.1_spec</artifactId>
                 <version>1.1.1</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-jta_1.2_spec</artifactId>
+                <version>1.0-alpha-1</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-jcdi_1.1_spec</artifactId>
+                <version>1.0</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-atinject_1.0_spec</artifactId>
+                <version>1.0</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-interceptor_1.2_spec</artifactId>
+                <version>1.0</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.geronimo.specs</groupId>
+                <artifactId>geronimo-annotation_1.2_spec</artifactId>
+                <version>1.0</version>
+            </dependency>
 
             <dependency>
                 <groupId>org.osgi</groupId>

http://git-wip-us.apache.org/repos/asf/aries-jpa/blob/ad5990d4/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 6a4e741..c5fa5a9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,6 +48,7 @@
         <module>jpa-container</module>
         <module>jpa-support</module>
         <module>jpa-blueprint</module>
+        <module>jpa-cdi</module>
         <module>jpa-container-eclipselink-adapter</module>
         <module>jpa-repository</module>
         <module>examples</module>