JPOX
JPOX
 Project  |  Ver 1.1  |  Ver 1.2  |  JDO  |  JPA  |  Guides  |  Tools
1.1 | Preparation | O/R Mapping | Runtime | Extensions | Developer
JPOX 1.1 Runtime
Runtime Tools
Queries
RDBMS Datastores
JPOX - Usage within a J2EE environment

The J2EE framework has become increasingly popular in the last 3 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). JPOX can be utilised within a J2EE environment via this JCA system, and we provide a Resource Adaptor (RAR file) containing this JCA adaptor allowing JPOX to be used with the likes of WebLogic and JBoss. Instructions are provided for the following J2EE servers

The provided JPOX JCA jar 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.

See also :



Requirements

To use JPOX with JCA the first thing that you will require is the jpox-{version}.rar file (available from the download section).



JPOX Resource Adaptor and transactions

A great advantage of JPOX 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 JPOXBean, your ejb-jar.xml should contain the following configuration elements:

<session>
	<ejb-name>JPOXBean</ejb-name>
	...
	<transaction-type>Container</transaction-type>
	...
<session>

Imagine your bean defines a method called testJPOXTrans():

<container-transaction>
    <method >
        <ejb-name>JPOXBean</ejb-name>
        ...
        <method-name>testJPOXTrans</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 JPOXBean 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:/jpox1";
	
    /**
     * 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 testJPOXTrans() 
    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 testJPOXTrans() 
    throws Exception
    {
        //...
    }

These instructions were adapted from a contribution by a JPOX user Alexander Bieber.



General configuration

You then need to open the rar file and edit the /META-INF/ra.xml to set your database connection properties. Finally you close the RAR file with your changes.

<?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>JPOX Connector</display-name>
    <description></description>
    <vendor-name>JPOX Team</vendor-name>
    <spec-version>1.0</spec-version>
    <eis-type>JDO Adaptor</eis-type>
    <version>1.0</version>
    <resourceadapter>
        <managedconnectionfactory-class>org.jpox.resource.ManagedConnectionFactoryImpl</managedconnectionfactory-class>
        <connectionfactory-interface>javax.resource.cci.ConnectionFactory</connectionfactory-interface>
        <connectionfactory-impl-class>org.jpox.resource.PersistenceManagerFactoryImpl</connectionfactory-impl-class>
        <connection-interface>javax.resource.cci.Connection</connection-interface>
        <connection-impl-class>org.jpox.resource.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>
        <config-property>
          <config-property-name>AutoCreateSchema</config-property-name>
          <config-property-type>boolean</config-property-type>
          <config-property-value>true</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>
                

The file shown above has a section for configuration properties. JPOX provides many, as described in the PMF Guide. You can specify these via JCA. The table below shows a selection of the config property names and types. Please refer to the list defined for the PersistenceManagerFactory for a complete list.

config-property-nameconfig-property-typeconfig-property-value
ConnectionURLjava.lang.String
ConnectionDriverNamejava.lang.String
ConnectionUserNamejava.lang.String
ConnectionPasswordjava.lang.String
ConnectionFactoryNamejava.lang.String
ConnectionFactory2Namejava.lang.String
Multithreadedbooleantrue | false
Optimisticbooleantrue | false
RetainValuesbooleantrue | false
RestoreValuesbooleantrue | false
NontransactionalReadbooleantrue | false
NontransactionalWritebooleantrue | false
IgnoreCachebooleantrue | false
Catalogjava.lang.String
Schemajava.lang.String
AutoCreateSchemabooleantrue | false
AutoCreateTablesbooleantrue | false
AutoCreateColumnsbooleantrue | false
AutoCreateConstraintsbooleantrue | false
CheckExistTablesOrViewsbooleantrue | false
ValidateTablesbooleantrue | false
ValidateConstraintsbooleantrue | false
AutoStartMechanismjava.lang.StringSchemaTable | None
AutoStartMechanismModejava.lang.StringQuiet | Ignored | Checked
TransactionIsolationint
UseUpdateLockbooleantrue | false
IdentifierCasejava.lang.String
FullyQualifiedNamesbooleantrue | false
MetadataFileExtensionjava.lang.Stringjdo
DelayDatastoreOperationsEnabledbooleantrue | false
UniqueConstraintsMapInversebooleantrue | false
PersistentIdGeneratorjava.lang.String
PoidTransactionIsolationLevelint
PoidTransactionAttributejava.lang.String
JdoCacheLevel1Typejava.lang.Stringweak
JdoCacheLevel2booleantrue | false
JdoCacheLevel2Typejava.lang.StringDefault
JdoCacheLevel2CacheNamejava.lang.String
JdoCacheCollectionsbooleantrue | false


WebLogic

To use JPOX on Weblogic the first thing that you will require is the jpox-{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.

JBoss 3.0/3.2

To use JPOX on JBoss (Ver 3.2) the first thing that you will require is the jpox-{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 jpox-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>jpox</jndi-name>
        <adapter-display-name>JPOX 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>
        <config-property name="AutoCreateSchema"
            type="boolean">true</config-property>
    </tx-connection-factory>
  
    <tx-connection-factory>
        <jndi-name>jpox1</jndi-name>
        <adapter-display-name>JPOX 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>
        <config-property name="AutoCreateSchema"
            type="boolean">true</config-property>
    </tx-connection-factory>
  
    <tx-connection-factory>
        <jndi-name>jpox2</jndi-name>
        <adapter-display-name>JPOX 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>
        <config-property name="AutoCreateSchema"
            type="boolean">true</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 JPOX). With the above definition we can then use the JNDI names java:/jpox, java:/jpox1, and java:/jpox2 to refer to our datastores.

You are now set to work on JPOX-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 pmFactory=(PersistenceManagerFactory)context.lookup("java:/jpox1");

These instructions were adapted from a contribution by a JPOX user Marco Schulze.



JBoss 4.0

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 JPOX JCA adapter for Apache Derby DBMS.

To use JPOX on JBoss 4.0 the first thing that you will require is the jpox-{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 Apache Derby you need to copy db2jcc.jar and db2jcc_license_c.jar.

You then create a file, also in the deploy directory with name jpox-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>jpox</jndi-name>
        <rar-name>jpox-{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>
        <config-property name="AutoCreateSchema"
            type="boolean">true</config-property>
        <config-property name="ValidateTables"
            type="boolean">false</config-property>
        <config-property name="ValidateConstraints"
            type="boolean">false</config-property>
    </tx-connection-factory>
</connection-factories>

You are now set to work on JPOX-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:/jpox");

These instructions were adapted from a contribution by a JPOX user Maciej Wegorkiewicz.