| Title: JPAProject |
| |
| # Aries JPA |
| |
| The Aries JPA project allows allows to use container managed persistence in OSGi in a modular and clean way. |
| |
| The core is the jpa.container module. It implements the "JPA Service Specification Version 1.0" from the OSGi |
| Enterprise Specification available for public download from the [OSGi Alliance](http://www.osgi.org/Download/Release4V42). |
| The jpa.blueprint module implements container managed persistence for Aries Blueprint using a programming model like in JEE. |
| The jpa.support module provides support for container managed persistence for DS and other injection frameworks using the |
| JPATemplate interface. |
| |
| See how it looks like in the See the [Aries JPA examples][1]. |
| |
| ## Source repository |
| |
| [Git repository aries-jpa][2] at apache. [Mirror of aries-jpa at github][3]. |
| |
| ## Persistence bundles |
| |
| A bundle is regarded as a persistence bundle if it contains the header **Meta-Persistence:** in it's Manifest. |
| The value of the Meta-Persistence: header is a comma separated list of locations where JPA persistence |
| descriptors can be found. If the header value is empty then a default of META-INF/persistence.xml is used. |
| The persistence bundle typically also contains the JPA entities. |
| |
| For example: |
| |
| Meta-Persistence: |
| |
| means that META-INF/persistence.xml will be searched for. For non standard locations: |
| |
| Meta-Persistence: persistence/myPu.xml, pUnit.jar!/someFolder/anotherPu.xml |
| |
| means that the locations "persistence/myPu.xml" (relative to the root of the bundle), and |
| "someFolder/anotherPu.xml" (relative to the root of pUnit.jar, which is in the root of |
| the bundle) will be searched. |
| |
| ## The Aries JPA 2 modules |
| |
| Aries JPA consists of four bundles. |
| |
| ### Aries JPA container (org.apache.aries.jpa.container) |
| |
| The Aries JPA container bundle implements the OSGi JPA service specification. It tracks persistence unit bundles and |
| creates an EntityManagerFactory service as soon as all dependencies are met. |
| |
| #### Specifying the PersistenceProvider |
| |
| For each persistence unit jpa container first determines which persistence provider to use by analyzing the "provider" property of persistence.xml. |
| It will track a PersistenceProvider service that matches this name. If no such property is defined then the first |
| PersistenceProvider service found will be used. |
| |
| #### Specifying a DataSource |
| |
| The next step is to configure a DataSource. There are two ways to do this. The spec conform way is to use the database properties to determine which |
| DataSourceFactory service to use and to configure it. |
| |
| Additionally aries jpa supports refering to a DataSource service using the jta-datasource or non-jta-datasource properties. The syntax is the aries jndi syntax to search for services. |
| |
| #### Properties of the published EntityManagerFactory service |
| |
| The EntityManagerFactory services will be registered with the following properties: |
| |
| * osgi.unit.name: this is the name of the persistence unit |
| * osgi.unit.provider: this is the class name of the JPA PersistenceProvider that was used to create the EntityManagerFactory |
| * org.apache.aries.jpa.container.managed: this property will be set to true, indicating this is a managed EntityManagerFactory. |
| |
| #### Useful notes |
| |
| * If using a JTA persistence unit keep in mind that you still have to supply a javax.sql.DataSource not an XADataSource. This DataSource must wrap an XADataSource and provide XA resource enlistment. The simplest way to achieve this is to use pax-jdbc. |
| * As soon as PersistenceProvider and DataSource are available the EntityManagerFactory service is created. |
| Aries JPA container also supports classpath scanning and load time weaving of JPA entities. |
| * You should never call close on the EntityManagerFactory service. This call will be made by the container when |
| the persistence bundle is removed or refreshed. If you do close the EntityManagerFactory service then it will be |
| closed for **all** users of the service. |
| |
| ### Aries JPA API (org.apache.aries.jpa.api) |
| |
| A set of interfaces to make it easier to use JPA in OSGi. It contains two main interfaces: |
| |
| * EmSupplier (**deprecated**): Allows to get a thread safe EntityManager and mark entry and exit of blocks that access the EntityManager. This |
| is rather low level and meant to be used mainly by frameworks. |
| * JpaTemplate: Allows to write closures that can safely access an EntityManager and are executed inside a transaction. |
| |
| ### Aries JPA support(org.apache.aries.jpa.support) |
| |
| For each EntityManagerFactory service this bundle provides additional services not defined in the OSGi spec that make it |
| easier to use JPA without blueprint. |
| |
| * EmSuppler (**deprectaed**): Use the new thread safe EntityManager instead. |
| * EntityManager: Thread safe EntityManager. Requires to be run inside a Coordination |
| * JPATemplate: Is used similar to the spring JPATemplate. it takes care of the EntityManager lifecycle and transaction handling |
| |
| #### Thread safe EntityManager |
| |
| The plain EntityManager provided by the PersistenceProvider may only be used by one thread at a time. This is ok for EJB |
| where there is a thread pool but not for OSGi where tpyically each class is just instantiated once and meant to be used |
| multi threaded. |
| |
| So Aries JPA provides a thread safe EntityManager that can be safely used. An OSGi Coordinator service is used to bind the |
| EntityManager to a thread and to manage its lifecycle. So to use the EntityManager service you need to make sure you only |
| call it inside a Coordination. The EntityManager will be created on first access and bound to the Coordination. When the |
| outermost Coordination of the current thread exits the EntityManager will be closed. So typically the EntityManager is |
| created per Request. |
| |
| Most users will not use the EntityManager service directly and instead either use the blueprint based Annotations or the JPATemplate. |
| Both of these approaches take care of the transaction and Coordination handling transparently. |
| |
| ### Aries JPA blueprint extension (org.apache.aries.jpa.blueprint) |
| |
| Provides a blueprint extension for @PersistenceUnit and @PersistenceContext injection. |
| To use the extension add this namespace to your blueprint |
| |
| xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0" |
| |
| and enable annotation support using the element <jpa:enable /> on top level. |
| Typically this namespace is used together with the transaction namespace to also provide annoation based transactions. |
| |
| For more details see the [Aries JPA blueprint example](https://svn.apache.org/repos/asf/aries/trunk/jpa/examples/tasklist-blueprint/). |
| |
| # Creation of a JPA project using Maven |
| |
| The first step consist in to create a maven module and make the following modifications to allow to deploy |
| it as OSGI bundle on the platform and reference where the persistence XML file must loaded by the classpath to |
| allow to the JPA container to configure the project accordingly. |
| |
| **Step 1 : Create a bundle ** |
| |
| OSGi bundles are mostly regular jars but they need to contain some special OSGi headers in the Manifest. The two changes make sure your maven project creates |
| a valid OSGi bundle. |
| |
| <packaging>bundle</packaging> |
| |
| and that you must configure the maven-bundle-plugin (http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html) |
| to generate the MANIFEST.MF file required by OSGI platform. |
| |
| <plugin> |
| <groupId>org.apache.felix</groupId> |
| <artifactId>maven-bundle-plugin</artifactId> |
| <version>2.5.4</version> |
| <extensions>true</extensions> |
| <inherited>true</inherited> |
| <configuration> |
| <instructions> |
| <!-- Only needed for the persistence bundle containing the jpa Entities --> |
| <Meta-Persistence>META-INF/persistence.xml</Meta-Persistence> |
| <!-- Needed for runtime enhancement when using hibernate --> |
| <Dynamic-Import-Package>*, org.hibernate.proxy, javassist.util.proxy</Dynamic-Import-Package> |
| </instructions> |
| </configuration> |
| </plugin> |
| |
| |
| **Step 2 : Adapt the persistence file** |
| |
| We will cover here how to modify a persistence.xml for OSGi usage. For the most part only the access to the DataSource has to be adapted for OSGi. |
| With J2EE applications, you simply use the jdbc key with the name of the datasource associated (jdbc/reportincidentdb). In OSGi jndi support is provided by aries jndi |
| (http://aries.apache.org/modules/jndiproject.html). It bridges jndi names to OSGi services. |
| We must define two parameters, the "osgi:service" wich will allow to lookup OSGI services, the interface "javax.sql.DataSource" and the name of the service "osgi.jndi.service.name", which is a filter property, with its jndi name associated. |
| |
| To access to the datasource, you must provide within the <jta-data-source> or <non-jta-data-source> depending if you use transaction type JTA or RESOURCE_LOCAL. |
| |
| <persistence-unit name="tasklist" transaction-type="JTA"> |
| <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=jdbc/tasklist)</jta-data-source> |
| |
| The other elements of the xml file are defined according to JPA specification. |
| |
| **Step 3.1 : Inject EntityManager into a bean and make it transactional ** |
| |
| The goal of this step is to provide a DAO layer that looks like JEE code on the java level. For this we need to inject |
| a thread safe EntityManager and ensure the DAO code is run inside a transational context. |
| |
| Aries JPA 1.x used a xml element inside each DAO bean to inject the EntityManager. This syntax is not suppoerted for Aries JPA 2.x anymore. |
| Instead simply enable standard @PesistenceContext and @PersistenceUnit annotation support with the xml element <jpa:enable/> on top level. |
| |
| The transactional context is established using the xml element <tx:transaction> on the bean level. In the example below we enable transactions for |
| all DAO methods. The scope of the transaction can be defined using the attribute value. |
| |
| Example blueprint follows showing the full breadth of allowable injection syntax: |
| |
| <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" |
| xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.2.0" |
| xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"> |
| <jpa:enable /> |
| <service ref="taskService" interface="org.apache.aries.jpa.example.tasklist.model.TaskService"/> |
| <bean class="org.apache.aries.jpa.example.tasklist.blueprint.impl.TaskServiceImpl"/> |
| <tx:transaction method="*"/> |
| </bean> |
| </blueprint> |
| |
| Make sure you inject the EntityManager in your DAO class like this: |
| |
| @PersistenceContext(unitName="tasklist") |
| EntityManager em; |
| |
| See tasklist-blueprint example for details. |
| |
| **Step 3.2 : Use JPATemplate to work with JPA in declarative services ** |
| |
| Inject the JPATemplate using a service reference: |
| |
| @Reference(target = "(osgi.unit.name=tasklist)") |
| public void setJpaTemplate(JpaTemplate jpa) { ... } |
| |
| Use the JPATemplate to work with JPA Entities inside closures. |
| |
| // txExpr if you need to return an object |
| return jpa.txExpr(TransactionType.Required, em -> em.find(Task.class, id)); |
| |
| // tx if you just execute code |
| jpa.tx(em -> em.persist(task)); |
| |
| See the tasklist-ds example for details. |
| |
| **Step 4 : Package the solution** |
| |
| To package the solution, execute a "maven clean install" instruction. Installing Aries JPA and Aries Transaction into arbitrary containers is beyond the scope of this document. |
| |
| ## Example ## |
| |
| To keep the installation instructions small we only cover installation into Apache Karaf 4.x. Karaf provides features for Aries JPA, |
| Aries Transaction, Hibernate and Pax-jdbc so installation is very easy. |
| |
| See the [README of the Aries JPA examples][4]. |
| |
| |
| [1]: https://github.com/apache/aries-jpa/tree/master/examples |
| [2]: https://git-wip-us.apache.org/repos/asf/aries-jpa.git |
| [3]: https://github.com/apache/aries-jpa |
| [4]: https://github.com/apache/aries-jpa/tree/master/examples |