|
|
managed_jpa_with_jta [2015/09/30 17:00] |
managed_jpa_with_jta [2021/04/05 11:23] (current) |
| ====== OSGi Container Managed JPA ====== |
| There are some tutorials and chapters out there on the net which describe how to setup JPA in OSGi but most described setups are too simple and can't be used in production. |
| |
| My requirements are |
| |
| * Apache Karaf |
| * PostgreSQL |
| * JPA 2.0 |
| * JTA |
| * Connection pool |
| * Configurable database connection properties |
| |
| <note important>This article describes a working setup and starting point to build upon which doesn't necessarily mean that it is the best solution for everybody.</note> |
| |
| <note important>**This does not seem to work with nested transactions and OpenJPA 2.2.2!** Instead use PAX-JDBC.</note> |
| |
| |
| ===== Apache Karaf ===== |
| I am using the current stable Apache Karaf 3 branch, Apache Karaf 3.0.3. |
| |
| I install certain features which I need for my setup: |
| |
| feature:install scr webconsole jndi jdbc |
| |
| |
| ==== Installed Features ==== |
| I later need to have the following features installed: |
| |
| transaction | 1.1.1 | x | enterprise-3.0.3 | OSGi Transaction Manager |
| jpa | 2.0.0 | x | enterprise-3.0.3 | OSGi Persistence Container |
| openjpa | 2.2.2 | x | enterprise-3.0.3 | Apache OpenJPA 2.2.x persistence engine support |
| jndi | 3.0.3 | x | enterprise-3.0.3 | OSGi Service Registry JNDI access |
| jdbc | 3.0.3 | x | enterprise-3.0.3 | JDBC service and commands |
| |
| |
| ===== JPA ===== |
| Apache Karaf makes it very easy to add JPA support. Just install the feature: |
| |
| feature:install jpa/2.0.0 openjpa/2.2.2 |
| |
| |
| ===== JTA ===== |
| The transaction support is as easily installed as the JPA support. |
| |
| feature:install transactions/1.1.1 |
| |
| |
| ==== Using Transactions ==== |
| To use transactions in a service component and provide an ''EntityManager'' to that component the OSGi Blueprint service can be used. Just declare the Blueprint bean and expose it as an OSGi service. |
| |
| <sxh xml> |
| <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" |
| xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0" xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0"> |
| |
| <bean id="contactPersonService" class="sdm.service.crm.ContactPersonService"> |
| <tx:transaction method="*" value="Required" /> |
| <jpa:context property="entityManager" unitname="sdm" /> |
| </bean> |
| <service id="sdmContactPersonService" ref="contactPersonService" interface="sdm.api.IContactPersonService" /> |
| </blueprint> |
| </sxh> |
| |
| |
| ===== PostgreSQL ===== |
| PostgreSQL doesn't supply a bundle for its driver but luckily the Apache Service Mix project repackages the database driver. It can be retrieved from the standard Maven repository. |
| |
| http://search.maven.org/#search%7Cga%7C1%7Corg.apache.servicemix.bundles.postgresql |
| |
| The bundle just needs to be dropped into the deploy folder for deployment. |
| |
| The bundle needs to be started prior to the JPA stuff so the bundle start level needs to be set to a lower value. |
| |
| bundle:start-level <postgres-bundle-id> 25 |
| |
| |
| ===== Data Sources ===== |
| Data sources are created as OSGi services via blueprint. Create the ''blueprint.xml'' in a bundle in the folder ''OSGI-INF/blueprint''. This is the default location which can be configured in the MANIFEST.MF, see manifest file entry ''Bundle-Blueprint''. |
| |
| <sxh xml> |
| <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:jpa="http://aries.apache.org/xmlns/jpa/v1.0.0" |
| xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.0.0" |
| xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"> |
| |
| <reference id="transactionManager" interface="javax.transaction.TransactionManager" /> |
| |
| <!-- Configuration Admin suppport --> |
| <cm:property-placeholder persistent-id="sdm.persistence.datasource" update-strategy="reload" /> |
| |
| <bean class="org.postgresql.xa.PGXADataSource" id="xaDatasource"> |
| <property name="serverName" value="${host}" /> |
| <property name="databaseName" value="${database}" /> |
| <property name="user" value="${user}" /> |
| <property name="password" value="${password}" /> |
| </bean> |
| |
| <bean class="org.apache.commons.dbcp2.managed.BasicManagedDataSource" id="xaSdsDatasource" destroy-method="close"> |
| <property name="xaDataSourceInstance" ref="xaDatasource" /> |
| <property name="transactionManager" ref="transactionManager" /> |
| <property name="maxTotal" value="25" /> |
| <property name="initialSize" value="3" /> |
| </bean> |
| |
| <service id="xaSdsDS" interface="javax.sql.DataSource" ref="xaSdsDatasource"> |
| <service-properties> |
| <entry key="osgi.jndi.service.name" value="jdbc/xasds" /> |
| </service-properties> |
| </service> |
| |
| </blueprint> |
| </sxh> |
| |
| ==== Connection Pooling ==== |
| I am using the PostgreSQL XA datasource as a base data source and configure the [[https://commons.apache.org/proper/commons-dbcp/apidocs/org/apache/commons/dbcp2/managed/BasicManagedDataSource.html | BasicManagedDataSource]] from the //commons-dbcp2// to use it as a data source for retrieving connections: |
| |
| <property name="xaDataSourceInstance" ref="xaDatasource" /> |
| |
| ==== Configurable database connection properties ==== |
| The database connection properties are configured via the OSGi ConfigAdmin service. |
| |
| The configuration file ''sdm.persistence.database.cfg'' need to be created in the ''<karaf_home>/etc'' folder. |
| |
| service.pid=sdm.persistence.datasource |
| host=dbserver |
| database=dbname |
| user=dbuser |
| password=dbsecret |
| |
| To tell blueprint to use the configuration from this configuration the following line was added to the ''blueprint.xml'' file. |
| |
| <cm:property-placeholder persistent-id="sdm.persistence.datasource" update-strategy="reload" /> |
| |
| Now the configuration can be accessed by its keys like ''${host}'' and it doesn't have to be packaged with the bundles. |
| |
| Parameters like ''maxTotal'' and ''initialSize'' needs to be adjusted to the environment. |
| |
| === Needed Bundles === |
| For connection pooling the projects ''commons-dbcp2'' and ''commons-pool2'' are needed which already package their software as bundles and can be retrieved from the standard Maven repository. |
| |
| I have used |
| |
| * commons-pool2 2.4.1 |
| * commons-dbcp2 2.1 |
| |
| |
| ===== persistence.xml ===== |
| <sxh xml> |
| <?xml version="1.0" encoding="UTF-8"?> |
| <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="sdm" transaction-type="JTA"> |
| <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> |
| |
| <jta-data-source>osgi:service/jdbc/xasds</jta-data-source> |
| |
| <class>sdm.data.Entity</class> |
| |
| <properties> |
| <property name="openjpa.Log" value="File=/tmp/org.apache.openjpa.log, DefaultLevel=TRACE" /> |
| <property name="openjpa.RuntimeUnenhancedClasses" value="supported" /> |
| </properties> |
| |
| </persistence-unit> |
| |
| </persistence> |
| |
| </sxh> |
| |
| |
| ===== FAQ ===== |
| |
| ==== Unsatisfied requirement(s): service:(service=javax.transaction.TransactionManager) ==== |
| If the feature ''obr'' is installed prior to the installation of the feature ''openjpa'' it won't install the feature ''openjpa''. |
| |
| <sxh> |
| karaf@root()> feature:install obr |
| |
| karaf@root()> feature:install openjpa |
| |
| Error executing command: Can't install feature openjpa/0.0.0: |
| |
| Can not resolve feature: |
| |
| Unsatisfied requirement(s): |
| |
| --------------------------- |
| |
| service:(service=javax.transaction.TransactionManager) |
| |
| Apache Aries Transaction Blueprint |
| </sxh> |
| |
| |
| ===== Links ===== |
| * [[http://karaf.apache.org | Apache Karaf]] |
| * [[http://search.maven.org | Search Maven Repository]] |
| * [[https://aries.apache.org | Apache Aries - OSGi Enterprise]] |
| |
| {{tag>osgi karaf java}} |