Connection Pooling with JPA and Apache Karaf
This has been tested with Apache Karaf 3.0.3 and by installing the following features:
feature:install scr jpa/2.0.0 openjpa/2.2.2 transaction jndi jdbc
JDBC Driver
PostgreSQL is used in this example. The driver can be retrieved as a bundle from the Apache Servicemix project. Look in the Maven Repository for org.apache.servicemix.bundles.postgresql
.
Just drop the bundle into the deploy
folder and set the bundle start level to 25.
DataSource
The javax.sql.DataSource
instances will be created via Blueprint. Create a OSGI-INF/blueprint/blueprint.xml
file in your project which looks like this:
<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.ds.PGSimpleDataSource" id="sdsDatasource"> <property name="serverName" value="${host}" /> <property name="databaseName" value="${database}" /> <property name="user" value="${user}" /> <property name="password" value="${password}" /> </bean> <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="sdsDS" interface="javax.sql.DataSource" ref="sdsDatasource"> <service-properties> <entry key="osgi.jndi.service.name" value="jdbc/sds" /> </service-properties> </service> <service id="xaSdsDS" interface="javax.sql.DataSource" ref="xaSdsDatasource"> <service-properties> <entry key="osgi.jndi.service.name" value="jdbc/xasds" /> </service-properties> </service> </blueprint>
If you have any questions about this file, look at the OSGi Blueprint specs.
BasicManagedDataSource
is packaged in the commons-dbcp2
project (which has a dependency to commons-pool2
). Both projects are already packaged as bundles and can be fetched from the maven repository.
The placeholders are filled by the ConfigAdmin service. It uses the configuration file sdm.persistence.datasource as stated in the attribute persistent-id
which resides in the etc
folder of Karaf. It may look something like this:
service.pid=sdm.persistence.datasource host=server database=my_db user=sgbs password=sgbs
The DataSource instances can be checked via
service:list DataSource
JPA
Now the JPA needs to use our DataSource instances for getting a connection. This can be done in the persistence.xml
file.
It may look something like this:
<?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> <non-jta-data-source>osgi:service/jdbc/sds</non-jta-data-source> <class>my.jpa.EntityClass</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>
Other Solutions
Pax JDBC
The project Pax JDBC offers a nice solution to for creating DataSource objects via ConfigAdmin and also supports connection pooling.