Chapter 7. Container-Managed Persistence

The Duke’s Bank application uses bean-managed persistence (BMP).
However, the improvements to container-managed persistence (CMP)
introduced in the EJB 2.0 specification make it unlikely that you
would use BMP in practice. In this chapter we’ll look at the
RosterApp example application from the J2EE
tutorial which covers the use of container-managed persistence and
relationships. You should read through the CMP tutorial notes before
proceeding so that you have a good overview of the beans and their relationships.

You’ll find the code in
j2eetutorial14/examples/ejb/cmproster. The
application implements a player roster for sports’ teams playing in
leagues. There are three entity beans PlayerEJB,
TeamEJB and LeagueEJB and a
single session bean, RosterEJB, which manipulates
them and provides the business methods accessed by the client
application. Only the session bean has a remote interface.

7.1. Building the Example

The EJBs are packaged in two separate JAR files, one for the
entity beans and one for the session bean. As before, we’ve
provided an ejb-jar.xml file for each one.
You don’t need a jboss.xml file for this
example. All the CMP information needed to build the database
schema is included in the standard descriptor. We’ll look at
JBoss-specific customization later.

To compile the code, first make sure you’re in the
examples directory. Running the
compile-cmp target will compile all the code
in one go.

ant -f jboss-build.xml compile-cmp

Run the following package-team to build the
team JAR file which contains the entity beans.

ant -f jboss-build.xml package-team

The package-roster target builds the
roster JAR.

ant -f jboss-build.xml package-roster

Both JAR files will be created in the jar
directory. Build the client jar using the
package-roster-client target.

ant -f jboss-build.xml package-roster-client

Finally assemble the RosterApp EAR using the
assemble-roster target.

ant -f jboss-build.xml assemble-roster

7.2. Deploying and Running the Application

Deploying the application is done with the
deploy-cmp Ant target.

ant -f jboss-build.xml deploy-cmp

Copy the RosterApp.ear file from the
jar directory to the JBoss
deploy directory (or run Ant with the
deploy-cmp target) and check the output from
the server.

There are a few things worth noting here. In the Duke’s Bank
application, we specified the JNDI name we wanted a particular
EJBHome reference to be bound under in the
jboss.xml file. Without that information
JBoss will default to using the EJB name. So the session bean is
bound under RosterBean and so on. You can
check these in the JMX Console as before.

The first time you deploy the application, JBoss will
automatically create the required database tables. If you take a
look at the database schema (as we did in Section 4.1.7.3, “The HSQL Database Manager Tool”), you will see that JBoss has created one
table for each entity bean and an addition join table needed to
handle the many-to-many relationship between players and teams.
The table and column names correspond the names of the entity
beans and their attributes. If these names are suitable, you
won't need to further refine the schema. In this case we've had
to manually map the position field on
PlayerBean to a column named
pos because the default column name,
position, is a reserved token in HSQL. The
schema is in the jbosscmp-jdbc.xml file.

Note that if you increase the logging level for the
org.jboss.ejb.plugins.cmp package (Section 2.2.2, “Logging Service”) to DEBUG, the
engine will log the SQL commands which it is executing. This can
be useful in understanding how the engine works and how the
various tuning parameters affect the loading of data.

7.2.1. Running the Client

The client performs some data creation and retrieval
operations via the session bean interface. It creates
leagues, teams and players which will be inserted into the
database. The session bean methods it calls to retrieve data
are mainly wrappers for EJB finder methods. The command to
run the client and the expected output are shown below.

Note that the client doesn’t remove the data, so if you
run it twice it will fail because it tries to create
entities which already exist! If you want to run it again
you’ll have to remove the data. The easiest way to do this
(if you’re using HSQL) is to delete the contents of the
data/hypersonic directory in the server
configuration you are using (assuming you don’t have any
other important data in there) and restart the server. We’ve
also provided a simple delete SQL script which you can run
with the db-delete target.

ant -f jboss-build.xml db-delete

You could also use SQL commands directly through the HSQL
Manager tool to delete the data.

7.3. CMP Customization

There are many ways you can further customize the CMP
engine’s behaviour by using the
jbosscmp-jdbc.xml file. It is used for basic
information such as the datasource name and type-mapping
(Hypersonic, Oracle etc.) and whether the database tables should
be automatically created on deployment and deleted on shutdown.
You can customize the names of database tables and columns which
the EJBs are mapped to and you can also tune the way in which
the engine loads the data depending on how you expect it to be
used. For example, by using the read-ahead
element you can get it to read and cache blocks of data for
multiple EJBs with a single SQL call, anticipating further
access. Eager-loading groups can be specified, meaning that only
some fields are loaded initially with the entity; the others are
lazy-loaded if and when they are required. The accessing of
relationships between EJBs can be tuned using similar
mechanisms. This flexibility is impossible to achieve if you are
using BMP where each bean must be loaded with a single SQL call.
If on top of that you include having to write all your SQL and
relationship management code by hand then the choice should be
obvious. You should rarely, if ever, have to use BMP in your applications.

The details of tuning the CMP engine are beyond the scope of
this document but you can get an idea of what’s available by
examining the DTD
(docs/dtd/jbosscmp-jdbc_3_2.dtd) which is
well commented. There is also a standard setup in the
conf directory called
standardjbosscmp-jdbc.xml which contains
values for the default settings and a list of type-mappings for
common databases. The beginning of the file is shown below.

You can see that, among other things, this sets the
datasource and mapping for use with the embedded Hypersonic
database and sets table-creation to true and removal to false,
so the schema will be created if it doesn’t already exist. The
read-only and
read-time-out elements specify whether data
should be read-only and the time in milliseconds it is valid
for. Note that many of these elements can be used at different
granularities such as per-entity or even on a field-by-field
basis (consult the DTD for details). The
read-ahead element uses an
on-load strategy which means that the EJB
data will be loaded when it is accessed (rather than when the
finder method is called) and the page-size
setting means that the data for up to 1000 entities will be
loaded with one SQL command. You can override this either in
your own jbosscmp-jdbc.xml file’s list of
default settings or by adding the information to a specific
query configuration in the file.

A comprehensive explanation of the CMP engine and its various
loading strategies can be found in the full JBoss Admin. and
Development Guide.

7.3.1. XDoclet

Writing and maintaining deployment descriptors is a
labour-intensive and error-prone job at the best of times,
and detailed customization of the CMP engine can lead to
some large and complex files. If you are using CMP (or
indeed EJBs) in anger then it is worth learning to use the
XDoclet code generation engine (http://xdoclet.sourceforge.net/). Using
Javadoc-style attribute tags you place in your code, XDoclet
will generate the deployment descriptors for you as well as
the EJB interfaces and other artifacts if required. It fully
supports JBoss CMP, and though the learning curve is quite
steep, its use is thoroughly recommended (almost essential
in fact) for real projects.