Enterprise Java Beans

 


Overview

Enterprise JavaBean (EJB) is designed to be a scalable and flexible distributed framework for enterprise Java.

Although EJB is an incredibly powerful tool in the hands of experience architects, it is subject to a lot of misuse by novice developers who do not make sound choices. For example, some developers might use a BMP entity bean to map each database table in the system; or access entity beans directly from a distributed layer; or store large amount of data in session objects ... The list goes on. Although those approaches are technically possible, they are hardly the most efficient ways in most cases. Such problems have not only caused many projects to fail but also tarnished EJB's reputation. In fact, the complexity of EJB is often quoted as an argument for other enterprise platforms.

Session and message-driven beans are mainly used in the integration layers.

Entity EJBs are probably the most confusing types of components. Many experts have advocated to abolish entity EJBs altogether in favor of other simpler persistence frameworks such as the JDO or even simple JDBC facades.

Another big problem that even EJB developers recognize is the complexity of deployment descriptors.

Many J2EE projects steer clear of EJBs towards simpler solutions such as plain servlet/jsp with JDO for persistence, scaled horizontally through mod_jk or a hardware load balancer.

Here is a sample stack:

  1. Struts
  2. Hibernate
  3. GLUE
  4. Tomcat
  5. JDOM
  6. SonicMQ for messaging
  7. Oracle DBMS

To develop an enterprise bean, provide the following files:

Deployment descriptor XML file that specifies information about the bean such as its persistence type and transaction attributes. The deploytool utility creates the deployment descriptor when you step through the New Enterprise Bean wizard.
Enterprise bean class Methods defined in the following interfaces.
Interfaces Remote and home interfaces are required for remote access. For local access, the local and local home interfaces are required. Note that these interfaces are not used by message-driven beans.
Helper classes Classes needed by the enterprise bean class, such as exception and utility classes.

You package the files in the preceding list into an EJB JAR file, the module that stores the enterprise bean. An EJB JAR file is portable and may be used for different apps. To assemble a J2EE app, you package one or more modules--such as EJB JAR files--into an EAR file, the archive file that holds the app. When you deploy the EAR file that contains the bean's EJB JAR file, you also deploy the enterprise bean onto the J2EE server.


 

Naming Conventions for Enterprise Beans

Because enterprise beans are composed of multiple parts, it's useful to follow a naming convention for your apps.

 

Item
Syntax
Example
Enterprise bean name (DD) nameEJB AccountEJB
EJB JAR display name (DD) nameJAR AccountJAR
Enterprise bean class nameBean AccountBean
Home interface nameHome AccountHome
Remote interface name Account
Local home interface LocalnameHome LocalAccountHome
Local interface Localname LocalAccount
Abstract schema (DD) name Account

DD means that the item is an element in the bean's deployment descriptor.

 

The Life Cycles of Enterprise Beans

An enterprise bean goes through various stages during its lifetime, or life cycle. Each type of enterprise bean--session, entity, or message-driven--has a different life cycle.

The descriptions that follow refer to methods that are explained along with the code examples in the next two chapters. If you are new to enterprise beans, you should skip this section and try out the code examples first.

 

The Life Cycle of a Stateful Session Bean

Figure 3-3 illustrates the stages that a session bean passes through during its lifetime. The client initiates the life cycle by invoking the create method. The EJB container instantiates the bean and then invokes the setSessionContext and ejbCreate methods in the session bean. The bean is now ready to have its business methods invoked.

Figure 3-3 Life Cycle of a Stateful Session Bean

While in the ready stage, the EJB container may decide to deactivate, or passivate, the bean by moving it from memory to secondary storage. (Typically, the EJB container uses a least-recently-used algorithm to select a bean for passivation.) The EJB container invokes the bean's ejbPassivate method immediately before passivating it. If a client invokes a business method on the bean while it is in the passive stage, the EJB container activates the bean, moving it back to the ready stage, and then calls the bean's ejbActivate method.

At the end of the life cycle, the client invokes the remove method and the EJB container calls the bean's ejbRemove method. The bean's instance is ready for garbage collection.

Your code controls the invocation of only two life-cycle methods--the create and remove methods in the client. All other methods in Figure 3-3 are invoked by the EJB container. The ejbCreate method, for example, is inside the bean class, allowing you to perform certain operations right after the bean is instantiated. For instance, you may wish to connect to a database in the ejbCreate method.

 

The Life Cycle of a Stateless Session Bean

Because a stateless session bean is never passivated, its life cycle has just two stages: nonexistent and ready for the invocation of business methods. Figure 3-4 illustrates the stages of a stateless session bean.

Figure 3-4 Life Cycle of a Stateless Session Bean

 

The Life Cycle of an Entity Bean

Figure 3-5 shows the stages that an entity bean passes through during its lifetime. After the EJB container creates the instance, it calls the setEntityContext method of the entity bean class. The setEntityContext method passes the entity context to the bean.

After instantiation, the entity bean moves to a pool of available instances. While in the pooled stage, the instance is not associated with any particular EJB object identity. All instances in the pool are identical. The EJB container assigns an identity to an instance when moving it to the ready stage.

There are two paths from the pooled stage to the ready stage. On the first path, the client invokes the create method, causing the EJB container to call the ejbCreate and ejbPostCreate methods. On the second path, the EJB container invokes the ejbActivate method. While in the ready stage, an entity bean's business methods may be invoked.

There are also two paths from the ready stage to the pooled stage. First, a client may invoke the remove method, which causes the EJB container to call the ejbRemove method. Second, the EJB container may invoke the ejbPassivate method.

Figure 3-5 Life Cycle of an Entity Bean

At the end of the life cycle, the EJB container removes the instance from the pool and invokes the unsetEntityContext method.

In the pooled state, an instance is not associated with any particular EJB object identity. With bean-managed persistence, when the EJB container moves an instance from the pooled state to the ready state, it does not automatically set the primary key. Therefore, the ejbCreate and ejbActivate methods must assign a value to the primary key. If the primary key is incorrect, the ejbLoad and ejbStore methods cannot synchronize the instance variables with the database. In the section The SavingsAccountEJB Example, the ejbCreate method assigns the primary key from one of the input parameters. The ejbActivate method sets the primary key (id) as follows:

id = (String)context.getPrimaryKey();

In the pooled state, the values of the instance variables are not needed. You can make these instance variables eligible for garbage collection by setting them to null in the ejbPasssivate method.

 

The Life Cycle of a Message-Driven Bean

Figure 3-6 illustrates the stages in the life cycle of a message-driven bean.

The EJB container usually creates a pool of message-driven bean instances. For each instance, the EJB container instantiates the bean and performs these tasks:

  1. It calls the setMessageDrivenContext method to pass the context object to the instance.
  2. It calls the instance's ejbCreate method.

Figure 3-6 Life Cycle of a Message-Driven Bean

Like a stateless session bean, a message-driven bean is never passivated, and it has only two states: nonexistent and ready to receive messages.

At the end of the life cycle, the container calls the ejbRemove method. The bean's instance is then ready for garbage collection.