|
|
 |
Automatic Bean-Managed Persistence
A Technique for the Persistence of Enterprise JavaBeans Components
The Challenge
The persistence of Enterprise JavaBeans (EJB) components has become an
important issue in building scalable enterprise applications based
on the J2EE platform. Developers of EJB components are faced with
the following challenges:
- Differences in application server and database implementations
require runtime switches to make persistence code run in different
configurations (the EJB 1.1 specification does not fully specify how
container-managed persistence should be implemented, which allows for
application server vendor competition but makes persistence
implementations differ).
- Changes to the fields in a bean require a re-deployment
on the application server after the modification of a deployment
descriptor, which can often be a lengthy process during the
development cycle.
- The handling of the persistence of dependent classes is not
always the same in each application server (some break down the
fields in dependent classes while others store dependent classes
as a binary string).
- When using bean-managed persistence custom code is
required to prevent the component from storing fields that
have not changed.
- When using container-managed persistence custom finder methods are not always possible.
The Solution
Automatic Bean-Managed Persistence (ABMP) (patent-pending) addresses several of
the problems faced in EJB component persistence by keeping the persistence code separate
from the business logic. This separation provides a framework that allows for different
application server and database implementations and removes the need for a deployment
descriptor. It provides a portable persistence mechanism that moves with the EJB components
and insulates them from the application server and database.
Features
ABMP was created during the development of a real production EJB component suite. Its features include:
- Automatically implemented EJB persistence methods (ejbLoad(), ejbStore(), ejbCreate(), ejbRemove(), etc)
- Support for multiple application servers (J2EE Reference Implementation, WebLogic, JRun,
plus extensibility for other application servers)
- Support for multiple databases (Oracle, Cloudscape, SQL Server, plus
extensibility for other databases)
- Support for persisting all primitive Java types plus the automatic
breakdown of dependent classes into their corresponding fields
- Implementations of common finder methods
- Deployment descriptors do not need to be changed during the development
process when fields in dependent classes are added or changed
- Only fields that change are stored to the database on a call to ejbStore()
- Optional on-demand loading of fields for specific cases where
large fields must be stored
Implementation
Automatically implemented EJB persistence methods
ABMP is implemented using a superclass common to all EJB entity beans. This class,
AbstractAutoEntityBean, provides the implementations for the EJB
persistence methods and finder methods.
Initialization procedure and persistable field graph
When the bean is first initialized (in particular, when setEntityContext() is
called for the first time), the AbstractAutoEntityBean class uses introspection
to find all of the persistable fields in the bean. Each field is examined (with
the exception of transient fields) and mapped over to a corresponding field in
the database with the same name. Because the same name is used in both the bean
and the database, no deployment descriptor or additional persistence configuration
is required. After the field mapping is complete, the corresponding static parts of
the SQL statements for ejbLoad(), ejbStore(), ejbCreate() and ejbRemove() are generated.
Default implementations of all bean-managed persistence methods
After the initialization procedure completes, ABMP has a
mapping between the bean fields and database fields. With each call
to a business method, the pre-generated SQL statements are executed
to load and store all of the bean's fields. Introspection is used
to set the query parameters and get values from the result set.
Isolation from different database implementations
Although each JDBC compliant database supports the use of SQL,
they support it differently. For example, sometimes identifiers
need to be quoted and other times they must not be quoted. Occasionally,
stored procedures may even need to be used for persisting certain data
types. For this reason, an AbstractDatabasePersistence class exists to
insulate AbstractAutoEntityBean from database operations. For each
database, a different concrete class that extends
AbstractDatabasePersistence is created.
Implementations of finder methods
Since the AbstractAutoEntityBean class has a mapping of all
of the component fields over to the database fields, it has the
opportunity to implement common finder methods. Examples of finders
that are implemented are as follows:findByPrimaryKey() - Executes the SQL
statements needed to find an instance of the bean by its primary key field.
findByField() - Execute a SQL statement to find a list of bean instances
with fields that are equal to a specified value. Since this is a common
requirement, many finders will be able to use this method to avoid the
need for repetitive SQL statements.
findByFieldAndSort()- Execute a SQL statement to find a list of bean instances
with fields that are equal to a specified value, and return those
instances sorted by the same or another field.
As with the persistence methods, introspection is used in
the execution of the SQL statements to set request parameters
and get the responses. With the advent of the EJB 2.0 specification,
a query language is provided to help write finders that should
insulate developers from the need to write custom SQL code or
use an application server specific query tool. In this case
the finder methods that AbstractAutoEntityBean provides may
be deprecated.
Dependent classes
Instead of always creating a binary string out of dependent objects
using serialization, ABMP has the ability to map their individual fields
over to the database as well. During initialization time
AbstractAutoEntityBean finds all of the fields in dependent
classes that implement the IPersistable interface, and knows that
the fields in these classes should be mapped over to the database.
A database specific separator character (such as '$') is used to
separate the fields of dependent classes from their superclass. For
example, if in the class referenced by the bean field beanField there
is a field named referencedField, and the '$' character is used as a
separator for a certain database, the resulting database field name
will be beanField$referencedField. The nesting of referenced classes
may be arbitrarily deep. The separator character is used at each level
to indicate another nested field.
There is one additional database field per IPersistable object
that stores a boolean value stating whether or not the object is
null. By using this value an entire reference to a large
IPersistable class may be nulled by changing one database field.
Loading fields on demand
Occasionally there will be the need to persist a large field
in an entity bean. One example might be a large byte array. It
would become very expensive if every call to a business method
required that this field be loaded. Instead, the field may be
made transient, then loaded on demand. AbstractAutoEntityBean
provides a loadField() method to load a single field in the bean.
This method should be called in any business method that needs to
use the field.
Summary
ABMP helps overcome some significant benefits in developing
EJB entity beans, including isolation from application server and
database differences and rapid persistence configuration. Because
its field mapping is automatic, it is most useful in situations
where the user of the bean has no existing database schema. When
a more complicated mapping is required between the bean and an
existing relational database, an alternative mechanism should be used.
More Information
For more information on Compoze Software please visit http://www.compose.com.
Initialization Procedure (1)
ejbStore() (2)
ejbLoad() (3)
ejbStore() for IPersistable class (4)
UML Diagram of ABMP and ADP (5)
PRINTER FRIENDLY VERSION
|