In a previous article,
we tried to alleviate fears you may have had about building your first EJBs by
walking you through the implementation details of a simple stateless session
EJB. In this article, I will explore the important details of entity beans and
how they are used to encapsulate data entities to be accessed by business
objects.

Installing the EJB runtime and development environment

An EJB must be executed inside of
an EJB container; therefore you must install a J2EE-compliant
EJB container. To help you deploy your EJB, you also need a deployment tool.
The J2EE reference implementation from Sun contains an EJB container and an EJB
deployment tool. The J2EE reference implementation can be found in the J2EE development kit from Sun.

The J2EE development kit relies on the Java 2 SDK, Standard
Edition (J2SE) development kit, so you will need to download it as well. You
need the J2SE SDK to run the reference implementation J2EE server and to build
and run EJB applications.

Once you have downloaded the development kits, install them,
and select your desired location for each kit. Define an environment variable
named JAVA_HOME and point it to the install directory for the J2SE development
kit. Next define an environment variable named J2EE_HOME and point it to the
install directory for the J2EE development kit. Now, you are ready to begin
writing your entity bean.

Overview of entity beans

An entity bean is intended to represent the business logic
for an entity existing in persistent storage. Entity beans share some of the
same qualities that you would find in a relational database, for example:

  • Entity beans are persistent—An
    entity bean’s state exists beyond the lifetime of the application in which
    it is created, or for that matter, beyond the lifetime of the EJB
    container. This implies that the entity bean can be restored to its
    original state by the EJB container.
  • Entity beans allow shared access—They
    may be shared by multiple clients and the concurrency is handled by the
    container.
  • Entity beans have primary keys—Primary-key
    classes exist to identify an instance of an entity bean. The primary key
    contains all the information needed to find a persistent entity.
  • Entity beans may participate in
    relationships
    —Local interfaces have been introduced to manage
    relationships between beans.
  • Entity beans can participate in
    transactions
    —Since data can be accessed and changed by multiple
    clients, it is important for entity beans to be able to specify the
    transactional properties for their interaction. Transaction properties are
    specified declaratively in deployment descriptors and transaction
    boundaries are handled by the container.

The object-relational mapping implied by entity beans
requires that an entity bean be responsible for inserting, updating, selecting,
and removing data within the data source. This process of managing the
communication between the component and the data source is called persistence.
In other words, persistence is this process of writing the information to an
external data source.


Enterprise Java Bean resources


Entity bean persistence mechanisms

There are two types of persistence for entity beans:
bean-managed persistence (BMP) and container-managed persistence (CMP). With
BMP, the programmer is responsible to write all of the code within the entity
bean to access the data source. BMP allows more flexibility to the programmer
because all access to the data source is controlled by the programmer.

With CMP the EJB container handles all database access
required by the entity bean. As a result, the bean’s data-access code is not
coupled to a specific data source. This frees the programmer from writing any
of the data-access code and allows the entity bean to be deployed in different
containers and/or against different data-sources.

Entity bean relationships

Figure A
illustrates the relationships that exist between a client, an EJB container,
and entity beans:

Figure A

Entity Bean Interfaces and Classes

An entity bean is composed of a minimum of three mandatory
classes/interfaces and two optional interfaces (a local interface and a local
home interface). For our examples, we will implement a very simple entity bean
that sets or returns the username, password or name for a given user. We will
assume that the entity bean is to be applied against a table named
“user” containing three varchar
columns named “username”, “password”, and “name”.

The Component interface

The first mandatory class/interface is the Component
interface. The Component interface defines the business methods visible to an
EJB client and it must extend javax.ejb.EJBObject.
The code for our Component interface is as follows:

package com.jeffhanson.ejb;

import java.rmi.*;
import javax.ejb.*;

/**
 * User is a generic user.
 */
public interface User extends EJBObject
{
   public String getUsername()
      throws RemoteException;

   public void setUsername(String userName)
      throws RemoteException;

   public void setPassword(String text)
      throws RemoteException;

   public String getName()
      throws RemoteException;

   public void setName(String name)
      throws RemoteException;
}

The Home interface

The second mandatory class/interface is the Home interface. The
Home interface is used by a remote EJB client to obtain a reference to a bean’s
component interface and it must extend javax.ejb.EJBHome.

The Home interface defines the following methods:

  • Create—Creates an entity bean
    instance
  • Remove—Removes an entity bean
    instance
  • Finder methods—These methods
    “find” one or more entity bean instances. Finder method names
    must start with “find”. For a CMP entity bean, the finder method
    findByPrimaryKey must be
    defined.
  • Home methods—These methods act
    like static methods for an entity bean. Home methods can be called from
    the home interface (remote or local) to execute entity bean methods.

The code for our Home interface is as follows:

package com.jeffhanson.ejb;

import java.util.*;
import java.rmi.*;
import javax.ejb.*;

/**
 * UserHome is the remote home interface for the User entity bean.
 */
public interface UserHome extends EJBHome
{
   /**
    * Create user.
    */
   public User create(String username, String password, String name)
      throws RemoteException,
             CreateException;

   /**
    * Find user by primary key.
    */
   public User findByPrimaryKey(String key)
      throws RemoteException,
             FinderException;

   /**
    * Find all users.
    */
   public Collection findAll()
      throws RemoteException,
             FinderException;

   /**
    * Generate username.
    */
   public String generateUsername()
      throws RemoteException;
}

The Local Home interface

The first optional interface is the Local Home interface.
The Local Home interface is used by a local EJB client to obtain a reference to
a bean’s component interface and it must extend javax.ejb.EJBLocalHome.

Clients running in the same container as the entity bean,
use the local home interface to create, remove, and find instances of the
entity bean. The local home interface defines create, remove, finder methods,
and home methods, just like the remote home interface (Listing A).

The Local interface

The second optional interface is the Local interface, which
must extend javax.ejb.EJBLocalObject.
Clients running in the same container as the entity bean interact with the
entity bean via its Local interface, which defines the local business methods
of the entity bean.

package com.jeffhanson.ejb;

import javax.ejb.*;

/**
 * UserLocal is the local interface for the User entity bean.
 */
public interface UserLocal extends EJBLocalObject
{
   /** Get username. */
   public String getUsername();

   /** Set username. */
   public void setUsername(String userName);

   /** Set password. */
   public void setPassword(String text);

   /** Get name. */
   public String getName();

   /** Set name. */
   public void setName(String name);
}

The Enterprise Bean class

The third mandatory class/interface is the Enterprise Bean
class. The Enterprise Bean class supplies the implementation for the Component
interface and the Home interface. The Enterprise Bean class for a session EJB
must implement the javax.ejb.EntityBean
interface. The code for our Enterprise Bean class is in Listing B.

CMP configuration file

Finally, for your entity bean to be properly constructed by
an EJB container, you must tell the container the specifics about the database,
table, and field/column mappings to be generated and managed. The following
snippet is a typical example of a CMP configuration to use to declare your User
entity bean, a “user” table and the field/column mappings (Listing C).

Distinct beans

In this article, I explored the details of entity beans and
how they are used to encapsulate data entities to be accessed by business
objects. The EJB architecture defines three distinct types of enterprise beans;
session beans, entity beans and message-driven beans. Session beans and entity
beans are invoked synchronously by an enterprise bean client. Message-driven
beans (MDBs) are invoked by a message container, such as a publish/subscribe
topic.

In the next article, I will look at message-driven beans and
how they can be used to listen for Java Message Service (JMS) messages.