In-Depth

Leverage Today's JDO for Tomorrow's EJB

There is extensive overlap between the new EJB 3.0 specification and the mature JDO 2.0. Compare and contrast EJB''s substantial but essential changes to existing features in JDO.

Few among us can discount the impact of the Java 2 Platform, Enterprise Edition (J2EE) on application programming and deployment in IT infrastructures. Companies investing in this Java-based technology need to keep pace with this specification to obtain the scalability and flexibility they've been promised with their investments. The changes coming in the new Enterprise JavaBean (EJB) 3.0 specification for J2EE are substantial but essential for addressing the productivity and scalability concerns that have kept the critics ranting about the difficulty in using these platforms.

Let's take a look at these EJB 3.0 changes by providing a perspective on how they overlap with the Java Data Objects (JDO) 2.0 specification. You'll want to be ready to adopt the new EJB 3.0 specification when it reaches the maturity required for your production applications, and you can do that by leveraging the mature JDO standard today. Recent announcements from the specification leads of both JDO and EJB indicate that these two groups are now combining to provide a common API for Java persistence that addresses needs both inside and outside of the application server container.

It is worth noting that as of this writing the new EJB 3.0 specification is not complete and is in early draft review. There will be many clarifications of the proposed changes in behavior as the specification matures. However, one change in the new EJB 3.0 specification stands out fundamentally. The EntityBean is no more—well, at least in spirit. For obvious reasons there will be some continued support until organizations can switch over to the Plain Old Java Object (POJO) model of persistence.

Airy Persistence
The major goal of the EJB 3.0 specification is to provide a simpler persistence mechanism that is more aligned with the proper use of Java as an object-oriented language. The newer, lighter-weight persistence mechanism, POJO persistence, is an approach that will eliminate the heavyweight interfaces associated with EntityBeans and facilitate the use of object models found in today's model-driven designs. The plain old Java object behaves in a persistent way and adheres to the transactional semantics of a database application.

This POJO approach proposed in EJB 3.0 is the same approach that JDO has taken since its inception in 1999. This point, along with JDO's proven maturity and acceptance as a scalable, flexible persistence solution in the Java community, is what is driving these two initiatives together. Let's take a look at the specific features proposed in the EJB 3.0 draft and note how these coincide with features in JDO 2.0.

Key to the elimination of the EntityBean is the introduction of an object that is responsible for the life-cycle management of the domain objects exhibiting persistent characteristics. This new interface in the EJB 3.0 specification is referred to as the EntityManager. The EntityManager will be responsible for tracking the state of POJO objects that are persistent within the context of a database transaction. The EntityManager wraps a JDBC connection or data source and interface with the application server's transaction manager to achieve a unified transactional context across all POJO accesses. The application server will pool these EntityManagers just as it now pools data sources and JDBC connections.

In JDO there is an equivalent interface with the same responsibilities as the EntityManager that is called the PersistenceManager. Just as with EJB 3.0, the JDO PersistenceManager wraps a JDBC connection or data source and coordinates with the application server's transaction manager to provide life-cycle management within a transactional context. The only major difference between the EntityManager and the PersistenceManager is that in EJB 3.0 the EntityManager is tied to the application server container, while in JDO the PersistenceManager can manage POJO life cycles both inside and outside of the container context.

In addition, the PersistenceManager provides a richer set of behavioral characteristics regarding state management across transactional boundaries as well as outside a transactional context. You can think of the EntityManager as a subset of the behavior found in the PersistenceManager. Proposed behavior in the EntityManager and the corresponding behavior in the PersistenceManager are listed in Table 1. Now that the combining of the JDO and EJB expert groups under JSR 220 has been announced, you will see the merging of this behavior as the EntityManager extends its scope to address persistence outside the application server container.

To give you a glimpse as to what is to be expected when programming to this API, let's look at an example of creating a new object and storing it in the database. In this example, we assume an application server environment to give contrast with what you've seen in the past using EJB 2.1.

Debatable Methods
As usual you will have a SessionBean and the typical host of life-cycle methods. Of course, some of these will change, but the important point is that when the SessionBean comes into existence within the container it will have the opportunity to hook up with a managed transactional context coordinating with an EntityManager. Once you enter a remote method of the SessionBean, the container ensures automatically that you are in a transaction. The typical SessionBean and its methods will then look something like this:

public class AccountManager {

EntityManager manager;

public void setEntityManager(
  EntityManager mngr) {
this.manager = mngr;
}

public void makeDeposit(
  int acctID, long amount) {
Account acct = (
  Account)manager.find(
  "Account", acctID);
acct.deposit( amount );
}
}

Close inspection of this code presents some unanswered questions: What kind of SessionBean is the AccountManager? Where are the life-cycle methods? How to clarify answers to these and other questions is still up for debate. With the initial JSR 220 early draft specification, you would use annotations and injection mechanisms to get such clarifications. However, such approaches tie the implementation to JDK 1.5, which will not be adopted by major vendors of application servers for quite some time.

Therefore, there is some speculation that with the inclusion of the JDO expert group in the JSR 220 initiative, this required use of annotations will be relaxed to allow annotations and specification through XML metadata files read at the container initialization to allow for early adoption. Annotation additions can be easily automated by vendors when the time is right and organizations upgrade to JDK 1.5-compatible deployment platforms.

Worth noting is that the "entity" Account object itself appears to be just a plain old Java object. You're no longer required to use heavyweight home/remote interfaces to acquire a reference to a factory, which is invoked to find the instance. Instead, the SessionBean works with entities much like they were just in-memory Java objects, while behind the scenes the new implementation is handling the details for you. Similarly, from a client perspective you no longer are required to look up the SessionBean itself from a heavyweight interface. Instead, you will find it as any other Java resource through JNDI or through injection mechanisms provided by the implementation.

Another major area of improvement for EJB 3.0 is the elimination of only statically compiled access methods for the domain model, which in EJB 2.1 are referred to as the "finder" methods. These changes come in conjunction with new extensions to the EJBQL query implementation. New life-cycle management coupled with extended query support will eliminate the now infamous N+1 load problem found in the EJB 2.1 implementation. Those not familiar with this issue would recognize it as a performance problem caused by multiple (N+1) database calls to load a collection of N objects. In the new EJB 3.0 implementation, it will be possible to load all objects in a collection with a single database call that is consistent with the behavior found in the current JDO specification. Table 2 outlines new features proposed in EJBQL for the EJB 3.0 release and compares them to what is available in the JDO 2.0 release.

Mapping
Another area that EJB 3.0 is changing significantly is in its ability to support proper object-oriented concepts such as inheritance and polymorphism. Those changes introduce new complexities in how a model can get mapped to an underlying database. In the first release of EJB 3.0, the spec is targeting the requirement for inheritance mapping to a single table only, with differentiating columns. This approach is commonly referred to as Flat mapping. EJB 3.0 defines an optional Vertical mapping of an inheritance hierarchy that will define mapping of inherited classes to multiple JOINed tables. The spec is only requiring a form of Vertical mapping, which does not support a discriminating column (the PK columns are used to form the JOIN between super and subclass tables).

In addition, the EJB 3.0 specification calls for support of dependent classes, which are classes that do not have stand-alone identity and are embedded with the owning class. A dependent object is therefore automatically subject to state changes that happen to the owner object. For example, if an owner is deleted, then the dependent object is also deleted automatically. These dependent objects won't support inheritance in EJB 3.0, and you won't be able to have collections of them.

Mapping will undoubtedly be an area that undergoes lots of changes with revised releases of the EJB specification, as the initial spec does not really accommodate data models found in many existing database implementations. The ability to support existing databases and predefined data models is essential to enterprise integration with existing systems.

The JDO standard has always supported the full capabilities of the Java language, including inheritance and polymorphism. Mapping for inheritance hierarchies in JDO 2.0 includes super-class-table(Flat), new-table(Vertical), and no-table(Horizontal). Horizontal mapping maps inherited attributes to concrete class tables. This type of mapping facilitates models having abstract super classes with common attributes. Further, JDO 2.0 standardizes the relational mapping specification to ensure compatibility of mapping files across vendors. JDO also supports dependent objects including collections of them.

EJB 3.0 mapping can be thought of as a subset of the mapping found in JDO 2.0. The major difference in these two technologies, where they are mapping to the same data model, is in how you specify the mapping. In EJB 3.0, mapping is to be specified through annotations in the source code as defined in the JDK 1.5 release. The JDO 2.0 expert group did not want to tie the use of JDO to only JDK 1.5, so while annotations were considered, they will likely be made optional.

Instead, JDO requires the mapping to be specified in an XML file that has a standard format compatible with all JDO 2.0-compliant vendors. Some JDO vendors will support annotations as an optional feature until use of JDK 1.5 becomes more widely adopted, at which point the JDO specification will probably make it a mandatory feature. In EJB 3.0, annotations not only play a role in mapping, but deployment descriptors are going away in favor of annotations as a way of working with container context, environment, and resource lookup. This additional meta information is also captured in XML property files or defined at run time as part of Java Property objects in the JDO 2.0 standard.

Life-Cycle Management
Object life-cycle management is another area that is changing in the EJB 3.0 specification. Implementations of the life-cycle callback interfaces are becoming optional so that even SessionBeans do not need to implement them. If the SessionBean does implement them, then the container will call them appropriately. For example, setSessionContext() can still be implemented to know when a session bean is being instantiated into the container, at which point other resources could be hooked up to the bean. In addition, there are a few new life-cycle callback methods that are being added. These methods include the callbacks to notify when objects are being either turned into Data Access Objects (DAOs) or when existing DAOs are being brought back into a transactional context, namely the ejbMerge() and ejbDetach() callbacks. Table 3 summarizes the EJB 3.0 life-cycle callbacks and the corresponding JDO 2.0 equivalents.

The last area where EJB 3.0 will be making changes is in the area of security. The early draft EJB 3.0 specification indicates that it will be allowing the definition of metadata that will allow you to specify a security role having access for Create, Read, Update, and Delete (CRUD) operations. At this time the JDO 2.0 specification has no definition of security attributes.

Companies have a substantial investment in J2EE technology that supports their business infrastructure, and their imperative is to continue to leverage that investment in future initiatives. The sweeping changes in the coming release of the EJB 3.0 specification threaten the ability to make a smooth transition. Even worse, many organizations need these changes today, but implementations will not be available from vendors for years to come and possibly not until widespread adoption of JDK 1.5 and J2EE 1.5.

The JDO standard has been maturing for nearly five years and more than 15 vendors provide implementations of the standard. The JDO 2.0 standard has an 85 percent overlap with the EJB 3.0 specification—an overlap so great that JDO vendors will undoubtedly be the first implementers of the EJB 3.0 specification. Most vendors, like Versant Corporation, indicate that they will provide migration strategies and even support the multiple standards within their products until full adoption of the new JSR comes to fruition.

You can use JDO today and leverage that mature technology to keep pace with the coming changes in the J2EE platform. When EJB 3.0 is finalized you can convert at your next upgrade, virtually with the click of a button. Even better, JDO already works outside of your managed environments, which is a new requirement under JSR 220. You can adopt the standard of tomorrow today for all of your persistent application requirements, whether the application is a multitiered implementation or a simple client/server.