XA support in Apache Aries JPA - 7.0

Talend ESB Container Administration Guide

EnrichVersion
7.0
EnrichProdName
Talend Data Fabric
Talend Data Services Platform
Talend ESB
Talend MDM Platform
Talend Open Studio for ESB
Talend Real-Time Big Data Platform
task
Administration and Monitoring
Design and Development
Installation and Upgrade
EnrichPlatform
Talend ESB

Prerequisite is to have a correctly wrapped DataSource or DataSourceFactory like described above.

The next thing is to create a bundle for the JPA Entities. For the most part, this works like in JEE. The entities need to be correctly annotated and a persistence.xml should be put into META-INF/persistence. The main thing to keep in mind for OSGi is to add a special Manifest header Meta-Persistence: META-INF/persistence.xml which marks the bundle as containing a persistence unit and points to the location of the persistence.xml.

Aries JPA will monitor all bundles in state Starting and Active for the Meta-Persistence header above. It will then scan the persistence.xml and create a matching EntityManagerFactory and also an EntityManager as an OSGi service.

These services can then be leveraged in a second bundle that uses JPA to access the entities. The easiest way to do this is to leverage the blueprint-maven-plugin. It scans the classes for CDI/JEE annotations and creates a blueprint xml from them. The skeleton of a class using JPA would look like this:

@Singleton
@Transactional
public class BookRepositoryImpl {
    @PersistenceContext(unitName="ebook")
    EntityManager em;
}

@Singleton marks the class as a bean to be listed in the blueprint.xml. This is the major difference to CDI where it is not needed to mark beans in a special way.

@Transactional can be used on class or method level. An annotation on method level overrides the same on class level. By default, this will define a transaction of type TxType.Required. This is the typical type for methods that change JPA entities. It defines that the method will join a transaction if one exists, or create a new one if needed. For methods that only read data, the TxType.Supports can be used. It allows the method to participate in a transaction but also to run without. For a full description of the annotation, set the JTA 1.2 specification.

@PersistenceContext defines that the variable should be injected with the EntityManager of the named persistence unit. Aries JPA takes care of creating thread safe EntityManager that can be used like in JEE. The lifecycle of the EntityManager is bound to an OSGi Coordination. By default, the coordination spans that outermost call marked with @Transactional. This is important as the EntityManager itself is not thread safe, so Aries JPA internally needs to bind one instance to a thread but also needs to make sure the EntityManager is relatively short lived to avoid class loading problems in case of bundle restarts.

The user can also create a Coordination manually using the CoordinatorService. In the ebook example, this is done using a CXF interceptor that creates the coordination on the CXF level when a request is received and only ends it when the serialization is done. This makes the EntityManager available during serialization and allows to lazily load entities without the problem of having detached entities.