Welcome!

Open Source Authors: Liz McMillan, Maureen O'Gara, Jeremy Geelan, Reuven Cohen, Lavenya Dilip

Related Topics: Open Source, Java, Linux

Open Source: Article

Bridging the Gap Between Open Source and Commercial Applications

Part 2 - Migrating EJB 2.0 entity beans to Hibernate POJOs

Migrating EJB 2.0 entity beans to Hibernate POJOs is pretty straightforward. Like many applications, all of the data for HQ is stored in the database, and we need to map from the underlying data store to an object-oriented view. In EJB 2.0, you would model that data with entity beans. An entity bean is created and found through the Home interface, and its fields are modified through its Local/Remote interface. These interface classes are automatically generated when we use XDoclet to annotate our entity bean implementations. We define the actual implementations in *EJBImpl classes. For example, for each getter/setter, we annotate the following:

/**
* @ejb:interface-method
* @ejb:persistent-field
* @ejb:transaction type="SUPPORTS"
*/
public abstract String getName();
/**
* @ejb:interface-method
* @ejb:transaction type="MANDATORY"
*/
public abstract void setName(String name);

For all getters, we mark the transaction type as SUPPORTS so that it won't necessarily require a transaction. For all setters, the transaction type is MANDATORY, since modifications should be involved in a transaction. The same class file defines the create and finder methods, as well. The create method is a function body appropriately annotated with @ejb:create-method; and the finders are in EJBQL and written in pure annotation in this class file. In EJB 2.0, the concept of Local/Remote interfaces was introduced. We decided to go with only local interfaces for the entity beans so that they would not be accessible remotely, and thus bypass the permission checking that we do when they are accessed or modified. When we compile our code, out of each EJBImpl class, we automatically generate these additional classes:

  • LocalHome: The local home interface that contains the create and finder methods
  • Local: The local interface that contains the getter/setter methods
  • Util: The utility class that fetches the home interface with the appropriate JNDI name
The N+1 Database Problem
The problem with entity beans has been termed the "N+1 database problem", and it's referring to the number of database calls to access entity beans. If a finder was invoked on the LocalHome interface, it will execute a query equivalent to the following:

select pk from table where column = value

PK is the primary key of the object, and most often it's the ID column. When you load each entity bean into memory by accessing its fields, the container will then issue another query:

select * from table where id = pk

If you do the math, for N rows found, you will end up issuing N + 1 queries to the database, henceforth the "N+1 database problem". Wait, there's more. We find that EJBs have a nasty habit of aggressively locking up database rows or tables no matter how much we tried to mark methods read-only, setting the container to lock optimistically, or even marking transaction type as NOTSUPPORTED. Maybe we didn't try hard enough, but we definitely pulled a fair amount of hair out over this. In fact, we found ourselves replacing getId() calls with getPrimaryKey().getId(), because while the ID has already been fetched into the primary key, the container would still do a database lookup when we ask for the ID. We needed to avoid the extra table lookups and reduce the duration of transactions to a minimum.

The Value Objects
XDoclet provides the facilities for implementing the Value Object pattern. The motivation for the pattern is to avoid calls through the entity bean's interface for each method call, which can be either local or remote. We took it a step further: we create a Value object (sometimes more than one so that we can have "light" objects that would incur the additional burden of loading up the relationships, etc.) for each entity bean and make sure to convert any lookups of entity beans to Value objects, and then cache the Value objects. Now, when the system is properly cached, we should be able to drop the "N" part of the "N+1" lookups. We augmented XDoclet a bit to account for this caching functionality. In our EJBImpl class, we also annotate the following for the generation of Value objects:

   @ejb:value-object
      name="Resource"
      match="*"
      instantiation="eager"
      cacheable="true"
      cacheDuration="300000"

XDoclet will not only generate the Value object class, it will also generate an extension to our EJBImpl class to get/set its Value objects. Now this is starting to look a bit untidy. Take ResourceEBJImpl.java, for example; when we compile it, we get the following classes from one single file:

  • ResourceUtil
  • ResourceLocalHome
  • ResourceLocal
  • ResourceEJBImpl
  • ResourceValue
  • ResourceCMP
This simple task of mapping database tables to objects has quickly become cumbersome and error-prone. All these annotations and transaction problems can create bugs in areas that often cannot be detected until runtime.

More Stories By Charles Lee

Charles Lee is co-founder and vice-president of engineering of Hyperic. Prior to co-founding Hyperic, Lee was a senior software engineer at Covalent. There, he built Covalent's configuration management product for Apache (CMP), and he spearheaded and architected the application management software (CAM). Before Covalent, Lee developed a document management system for retail store build-outs based on open-source technology at WiseConnect. Lee also held senior engineering position at Hewlett-Packard, where he was instrumental in developing print drivers for network LaserJets for the Asian market, as well as developing the UI framework used for LaserJets for all markets. Lee also developed the first GUI printer configuration framework for AutoCAD while a senior engineer at Autodesk. Lee was an early engineer at Backflip, where he created the document publishing system for the website based on mod_perl.

Lee received his BS in Computer Science and BA in Chemistry with honors from the University of Washington.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.