How to use Castor with(in) distributed J2EE transactions

# How to use Castor with(in) distributed J2EE transactions

## Overview

J2EE applications depend on the J2EE container (hosting Servlet, EJB, etc) to configure a database connection (as well as other resource managers) and use JNDI to look it up. This model allows the application deployer to configure the database properties from a central place, and gives the J2EE container the ability to manage distributed transactions across multiple data sources.

This HOW-TO shows how to seamlessly use Castor JDO in such a managed environment, and how to make Castor participate in a distributed transaction.

## Intended audience

Anyone who wants to use Castor JDO with(in) distributed J2EE transactions.

## Steps

The following sections highlight the steps necessary to use Castor JDO seamlessly in such a (managed) environment, and how to make Castor participate in a distributed transaction.

### Make Castor participate in a J2EE transaction

The following code fragment shows how to use JNDI to lookup a database and how to use a JTA UserTransaction instance to manage the J2EE (aka distributed) transaction:

    // Lookup databse in JNDI
    Context ctx = new InitialContext();
    Database db = (Database) ctx.lookup( "java:comp/env/jdo/mydb" );

    // Begin a transaction
    UserTransaction ut = (UserTransaction) ctx.lookup( "java:comp/UserTransaction" );
    ut.begin();
    // Do something
    . . .
    // Commit the transaction, close database
    ut.commit();
    db.close();

### Make Castor participate in container-managed J2EE transaction

If the transaction is managed by the container, a common case with EJB beans and in particular entity beans, there is no need to begin/commit the transaction explicitly. Instead the application server takes care of enlisting the database used by Castor JDO to insert domain entities into a database in the ongoing transaction and commiting/rolling back at the relevant time.

The following code snippet relies on the container to manage the transaction.

    InitialContext  ctx;
    UserTransaction ut;
    Database        db;

    // Lookup databse in JNDI
    ctx = new InitialContext();
    db = (Database) ctx.lookup( "java:comp/env/jdo/mydb" );

    // Do something
    . . .
    // Close the database
    db.close();

As transaction enregistration is dealt with at the J2EE container, it is not necessary anymore to obtain a UserTransaction and start/commit the transaction manually.

### Resource enlisting

Instead of constructing required resources directly, a typical J2EE application uses the JNDI API to look up resources from centrally managed place such as a naming and directory service. In such an environment, Castor JDO takes on the role of a managed resource as well. It follows that, instead of constructing a org.exolab.castor.jdo.JDOManager directly, a typical J2EE application should use JNDI to look it up.

We thus recommend enlisting the JDOManager object under the `java:comp/env/jdo` namespace, compatible with the convention for listing JDBC resources.

## Tips

- When using Castor JDO in a J2EE environment, Castor allows you to enable a special Database instance pooling support. This option is configured via the org.exolab.castor.jdo.JDOManager.setDatabasePooling(boolean) method; by default, it is turned off. This option only affects JDOManager if J2EE transactions are used and if a transaction is associated with the thread that calls {@link #getDatabase}.

  If database pooling is enabled, JDOManager will first search in this special pool to see if there is already a org.exolab.castor.jdo.Database instance for the current transaction. If found, it returns this org.exolab.castor.jdo.Database instance; if not, it creates a new one, associates it will the transaction and returns the newly created org.exolab.castor.jdo.Database instance.

  Please make sure that you call this method before calling {@link #getDatabase}.

## References

- Other pooling examples