The J2EE framework has become popular in some places in the last few years. It provides a container
within which java processes operate and it provides mechanisms for, amongst other things,
transactions (JTA), and for connecting to other (3rd party) utilities (using Java Connector
Architecture, JCA). DataNucleus Access Platform can be utilised within a J2EE environment via this
JCA system, and we provide a Resource Adaptor (RAR file) containing this JCA adaptor allowing
Access Platform to be used with the likes of WebLogic and JBoss.
Instructions are provided for the following J2EE servers
The provided DataNucleus JCA rar provides default resource adapter descriptors, one general, and the
other for the WebLogic J2EE server. These resource adapter descriptors can be configured to meet your
needs, for example allowing XA transactions instead of the default Local transactions.
To use DataNucleus with JCA the first thing that you will require is the
datanucleus-jca-{version}.rar
file
(available from the download section).
A great advantage of DataNucleus implementing the ManagedConnection interface is that the J2EE
container manages transactions for you (no need to call the begin/commit/rollback-methods).
Currently, local transactions and distributed (XA) transactions are supported.
Within a J2EE environment, JDO transactions are nested in J2EE transactions.
All you have to do is to declare that a method needs transaction management. This is done in
the EJB meta data. Here you will see, how a SessionBean implementation could look like.
The EJB meta data is defined in a file called ejb-jar.xml and can be found in the META-INF
directory of the jar you deploy. Suppose you deploy a bean called DataNucleusBean, your
ejb-jar.xml should contain the following configuration elements:
<session>
<ejb-name>DataNucleusBean</ejb-name>
...
<transaction-type>Container</transaction-type>
...
<session>
Imagine your bean defines a method called testDataNucleusTrans():
<container-transaction>
<method >
<ejb-name>DataNucleusBean</ejb-name>
...
<method-name>testDataNucleusTrans</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
You hereby define that transaction management is required for this method. The container will
automatically begin a transaction for this method. It will be commited if no error occurs or
rolled back otherwise. A potential SessionBean implementation containing methods to retrieve a
PersistenceManager then could look like this:
public abstract class DataNucleusBean implements SessionBean
{
// EJB methods
public void ejbCreate()
throws CreateException
{
}
public void ejbRemove()
throws EJBException, RemoteException
{
}
// convenience methods to get
// a PersistenceManager
/**
* static final for the JNDI name of the PersistenceManagerFactory
*/
private static final String PMF_JNDI_NAME = "java:/datanucleus1";
/**
* Method to get the current InitialContext
*/
private InitialContext getInitialContext() throws NamingException
{
InitialContext initialContext = new InitialContext();
// or other code to create the InitialContext eg. new InitialContext(myProperies);
return initialContext;
}
/**
* Method to lookup the PersistenceManagerFactory
*/
private PersistenceManagerFactory getPersitenceManagerFactory(InitialContext context)
throws NamingException
{
return (PersistenceManagerFactory) context.lookup(PMF_JNDI_NAME);
}
/**
* Method to get a PersistenceManager
*/
public PersistenceManager getPersistenceManager()
throws NamingException
{
return getPersitenceManagerFactory(getInitialContext()).getPersistenceManager();
}
// Now finally the bean method within a transaction
public viod testDataNucleusTrans()
throws Exception
{
PersistenceManager pm = getPersistenceManager()
try {
// Do something with your PersistenceManager
} finally {
// close the PersistenceManager
pm.close();
}
}
}
Make sure, you close the PersistenceManager in your bean methods. If you don't, the J2EE server
will usually close it for you (one of the advantages), but of course not without a warning or
error message.
To avoid the need of editing multiple files, you could use
XDoclet to generate your classes and control the
metadata by xdoclet tags. The method declaration then would look like this:
/**
* @ejb.interface-method
* @ejb.transaction type="Required"
*/
public viod testDataNucleusTrans()
throws Exception
{
//...
}
These instructions were adapted from a contribution by a DataNucleus user Alexander Bieber.
When creating a PMF using the JCA adaptor, you should specify your persistence properties
using a persistence.xml or
jdoconfig.xml. This is because DataNucleus JCA adapter from version 1.2.2
does not support Java bean setters/getters for all properties - since it is an inefficient and
inflexible mechanism for property specification. The more recent
persistence.xml
and
jdoconfig.xml
methods lead to more extensible code.
A resource adapter has one central configuration file
/META-INF/ra.xml
which is located
within the rar file and which defines the default values for all instances of the resource
adapter (i.e. all instances of
PersistenceManagerFactory
). Additionally, it uses one or
more deployment descriptor files (in JBoss, for example, they are named
*-ds.xml
)
to set up the instances. In these files you can override the default values from the
ra.xml
.
Since it is bad practice (and inconvenient) to edit a library's archive (in this case the
datanucleus-jca-${version}.rar
) for changing the configuration (it makes updates more
complicated, for example), it is recommended, not to edit the
ra.xml
within DataNucleus'
rar file, but instead put all your configuration into your deployment descriptors. This way,
you have a clean separation of which files you maintain (your deployment descriptors)
and which files are maintained by others (the libraries you use and which you simply replace in
case of an update).
Nevertheless, you might prefer to declare default values in the
ra.xml
in certain
circumstances, so here's an example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE connector PUBLIC "-//Sun Microsystems, Inc.//DTD Connector 1.0//EN"
"http://java.sun.com/dtd/connector_1_0.dtd">
<connector>
<display-name>DataNucleus Connector</display-name>
<description></description>
<vendor-name>DataNucleus Team</vendor-name>
<spec-version>1.0</spec-version>
<eis-type>JDO Adaptor</eis-type>
<version>1.0</version>
<resourceadapter>
<managedconnectionfactory-class>org.datanucleus.jdo.connector.ManagedConnectionFactoryImpl</managedconnectionfactory-class>
<connectionfactory-interface>javax.resource.cci.ConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>org.datanucleus.jdo.connector.PersistenceManagerFactoryImpl</connectionfactory-impl-class>
<connection-interface>javax.resource.cci.Connection</connection-interface>
<connection-impl-class>org.datanucleus.jdo.connector.PersistenceManagerImpl</connection-impl-class>
<transaction-support>LocalTransaction</transaction-support>
<config-property>
<config-property-name>ConnectionFactoryName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>jdbc/ds</config-property-value>
</config-property>
<authentication-mechanism>
<authentication-mechanism-type>BasicPassword</authentication-mechanism-type>
<credential-interface>javax.resource.security.PasswordCredential</credential-interface>
</authentication-mechanism>
<reauthentication-support>false</reauthentication-support>
</resourceadapter>
</connector>
To define persistence properties you should make use of
persistence.xml
or
jdoconfig.xml
and refer to the documentation for persistence properties
for full details of the properties.
To use DataNucleus on Weblogic the first thing that you will require is the
datanucleus-{version}.rar
file. You then may need to edit the
/META-INF/weblogic-ra.xml
file to suit the exact version of your WebLogic
server (the included file is for WebLogic 8.1).
You then deploy the RAR file on your WebLogic server.
To use DataNucleus on JBoss (Ver 3.2) the first thing that you will require is the
datanucleus-{version}.rar
file. You should put this in the
deploy ("${JBOSS}/server/default/deploy/")
directory of your JBoss installation.
You then create a file, also in the
deploy
directory with name
datanucleus-ds.xml
.
To give a guide on what this file will typically include, see the following
<?xml version="1.0" encoding="UTF-8"?>
<connection-factories>
<tx-connection-factory>
<jndi-name>datanucleus</jndi-name>
<adapter-display-name>DataNucleus Connector</adapter-display-name>
<config-property name="ConnectionDriverName"
type="java.lang.String">com.mysql.jdbc.Driver</config-property>
<config-property name="ConnectionURL"
type="java.lang.String">jdbc:mysql://localhost/yourdbname</config-property>
<config-property name="UserName"
type="java.lang.String">yourusername</config-property>
<config-property name="Password"
type="java.lang.String">yourpassword</config-property>
</tx-connection-factory>
<tx-connection-factory>
<jndi-name>datanucleus1</jndi-name>
<adapter-display-name>DataNucleus Connector</adapter-display-name>
<config-property name="ConnectionDriverName"
type="java.lang.String">com.mysql.jdbc.Driver</config-property>
<config-property name="ConnectionURL"
type="java.lang.String">jdbc:mysql://localhost/yourdbname1</config-property>
<config-property name="UserName"
type="java.lang.String">yourusername</config-property>
<config-property name="Password"
type="java.lang.String">yourpassword</config-property>
</tx-connection-factory>
<tx-connection-factory>
<jndi-name>datanucleus2</jndi-name>
<adapter-display-name>DataNucleus Connector</adapter-display-name>
<config-property name="ConnectionDriverName"
type="java.lang.String">com.mysql.jdbc.Driver</config-property>
<config-property name="ConnectionURL"
type="java.lang.String">jdbc:mysql://localhost/yourdbname2</config-property>
<config-property name="UserName"
type="java.lang.String">yourusername</config-property>
<config-property name="Password"
type="java.lang.String">yourpassword</config-property>
</tx-connection-factory>
</connection-factories>
This example creates 3 connection factories to MySQL databases, but you can create as many or
as few as you require for your system to whichever databases you prefer (as long as they are
supported by DataNucleus). With the above definition we can
then use the JNDI names
java:/datanucleus
,
java:/datanucleus1
, and
java:/datanucleus2
to refer to our datastores.
Note, that you can use separate deployment descriptor files. That means, you could for example
create the three files
datanucleus1-ds.xml
,
datanucleus2-ds.xml
and
datanucleus3-ds.xml
with each declaring one
PersistenceManagerFactory
instance.
This is useful (or even required) if you need a distributed configuration. In this case, you
can use JBoss' hot deployment feature and deploy a new
PersistenceManagerFactory
, while
the server is running (and working with the existing PMFs): If you create a new
*-ds.xml
file (instead of modifying an existing one), the server does not undeploy anything (and thus
not interrupt ongoing work), but will only add the new connection factory to the JNDI.
You are now set to work on DataNucleus-enabling your actual application. As we have said, you can
use the above JNDI names to refer to the datastores, so you could do something like the following
to access the PersistenceManagerFactory to one of your databases.
import javax.jdo.PersistenceManagerFactory;
InitialContext context = new InitialContext();
PersistenceManagerFactory pmf = (PersistenceManagerFactory)context.lookup("java:/datanucleus1");
These instructions were adapted from a contribution by a DataNucleus user Marco Schulze.
With JBoss 4.0 there are some changes in configuration relative to JBoss 3.2 in order to allow use
some new features of JCA 1.5. Here you will see how to configure JBoss 4.0 to use with DataNucleus
JCA adapter for DB2.
To use DataNucleus on JBoss 4.0 the first thing that you will require is the
datanucleus-{version}.rar
file. You should put this in the deploy directory
("${JBOSS}/server/default/deploy/") of your JBoss installation.
Additionally, you have to remember to put any JDBC driver files to lib directory
("${JBOSS}/server/default/lib/") if JBoss does not have them installed by default.
In case of DB2 you need to copy db2jcc.jar and db2jcc_license_c.jar.
You then create a file, also in the deploy directory with name datanucleus-ds.xml.
To give a guide on what this file will typically include, see the following
<?xml version="1.0" encoding="UTF-8"?>
<connection-factories>
<tx-connection-factory>
<jndi-name>datanucleus</jndi-name>
<rar-name>datanucleus-{version}.rar</rar-name> <!-- the name here must be the same as JCA adapter filename -->
<connection-definition>javax.resource.cci.ConnectionFactory</connection-definition>
<config-property name="ConnectionDriverName"
type="java.lang.String">com.ibm.db2.jcc.DB2Driver</config-property>
<config-property name="ConnectionURL"
type="java.lang.String">jdbc:derby:net://localhost:1527/"directory_of_your_db_files"</config-property>
<config-property name="UserName"
type="java.lang.String">app</config-property>
<config-property name="Password"
type="java.lang.String">app</config-property>
</tx-connection-factory>
</connection-factories>
You are now set to work on DataNucleus-enabling your actual application. You can use the above
JNDI name to refer to the datastores, and so you could do something like the following to access the
PersistenceManagerFactory to one of your databases.
import javax.jdo.PersistenceManagerFactory;
InitialContext context=new InitialContext();
PersistenceManagerFactory pmFactory=(PersistenceManagerFactory)context.lookup("java:/datanucleus");
These instructions were adapted from a contribution by a DataNucleus user Maciej Wegorkiewicz.
To use DataNucleus on Jonas the first thing that you will require is the
datanucleus-{version}.rar
file. You then may need to edit the
/META-INF/jonas-ra.xml
file to suit the exact version of your Jonas server (the included file is tested for Jonas 4.8).
You then deploy the RAR file on your Jonas server.
DataNucleus JCA adapter supports both Local and XA transaction types. Local means that a transaction
will not have more than one resource managed by a Transaction Manager and XA means that multiple
resources are managed by the Transaction Manager. Use XA transaction, if DataNucleus is configured
to use data sources deployed in application servers, or if other resources such as JMS connections
are used in the same transaction, otherwise use Local transaction.
You need to configure the
ra.xml
file with the appropriate transaction support, which is
either
XATransaction
or
LocalTransaction
. See the example:
<connector>
<display-name>DataNucleus Connector</display-name>
<description></description>
<vendor-name>DataNucleus Team</vendor-name>
<spec-version>1.0</spec-version>
<eis-type>JDO Adaptor</eis-type>
<version>1.0</version>
<resourceadapter>
<managedconnectionfactory-class>org.datanucleus.jdo.connector.ManagedConnectionFactoryImpl</managedconnectionfactory-class>
<connectionfactory-interface>javax.resource.cci.ConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>org.datanucleus.jdo.connector.PersistenceManagerFactoryImpl</connectionfactory-impl-class>
<connection-interface>javax.resource.cci.Connection</connection-interface>
<connection-impl-class>org.datanucleus.jdo.connector.PersistenceManagerImpl</connection-impl-class>
<transaction-support>XATransaction</transaction-support> <!-- change this line -->
...
To use a data source, you have to configure the connection factory name in
ra.xml
file.
See the example:
<connector>
<display-name>DataNucleus Connector</display-name>
<description></description>
<vendor-name>DataNucleus Team</vendor-name>
<spec-version>1.0</spec-version>
<eis-type>JDO Adaptor</eis-type>
<version>1.0</version>
<resourceadapter>
<managedconnectionfactory-class>org.datanucleus.jdo.connector.ManagedConnectionFactoryImpl</managedconnectionfactory-class>
<connectionfactory-interface>javax.resource.cci.ConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>org.datanucleus.jdo.connector.PersistenceManagerFactoryImpl</connectionfactory-impl-class>
<connection-interface>javax.resource.cci.Connection</connection-interface>
<connection-impl-class>org.datanucleus.jdo.connector.PersistenceManagerImpl</connection-impl-class>
<transaction-support>XATransaction</transaction-support>
<config-property>
<config-property-name>ConnectionFactoryName</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>jndiName_for_datasource_1</config-property-value>
</config-property>
<config-property>
<config-property-name>ConnectionResourceType</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>JTA</config-property-value>
</config-property>
<config-property>
<config-property-name>ConnectionFactory2Name</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>jndiName_for_datasource_2</config-property-value>
</config-property>
...
See also :