This chapter looks at the characteristics and purpose of enterprise
beans. It describes the two basic types of enterprise beans and their
life cycles, and it provides an example of how enterprise beans can be
combined to create distributed, three-tiered applications.
An enterprise bean is a Java component that can be combined with other
enterprise beans and other Java components to create a distributed,
three-tiered application. There are two types of enterprise
beans:
- An entity bean encapsulates permanent data, which is stored in
a data source such as a database or a file system, and associated methods to
manipulate that data. In most cases, an entity bean must be accessed in
some transactional manner. Instances of an entity bean are unique and
they can be accessed by multiple users.
For example, the information about a bank account can be encapsulated in an
entity bean. An account entity bean might contain an account ID, an
account type (checking or savings), and a balance variable and methods to
manipulate these variables.
- A session bean encapsulates ephemeral (nonpermanent) data
associated with a particular EJB client. Unlike the data in an entity
bean, the data in a session bean is not stored in a permanent data source, and
no harm is caused if this data is lost. However, a session bean can
update data in an underlying database, usually by accessing an entity
bean. A session bean can also participate in a transaction.
When created, instances of a session bean are identical, though some
session beans can store semipermanent data that makes them unique at certain
points in their life cycle. A session bean is always associated with a
single client; attempts to make concurrent calls result in an exception
being thrown.
For example, the task associated with transferring funds between two bank
accounts can be encapsulated in a session bean. Such a transfer session
bean can find two instances of an account entity bean (by using the account
IDs), and then subtract a specified amount from one account and add the same
amount to the other account.
This section discusses the basics of entity beans.
Every entity bean must have the following components, which are illustrated in
Figure 3:
- Bean class--This class encapsulates the data for the
entity bean and contains the developer-implemented business methods that
access the data. It also contains the methods used by the container to
manage the life cycle of an entity bean instance. EJB clients (whether
they are other enterprise beans or user components such as servlets)
never access objects of this class directly; instead, they use
the container-generated classes associated with the home and remote interfaces
to manipulate the entity bean instance.
- Home interface--This interface defines the methods used by
the client to create, find, and remove instances of the entity bean.
This interface is implemented by the container during deployment in a class
known generically as the EJB home class; instances are
referred to as EJB home objects.
- Remote interface--Once the client has used the home
interface to gain access to an entity bean, it uses this interface to invoke
indirectly the business methods implemented in the bean class. This
interface is implemented by the container during deployment in a class known
generically as the EJB object class; instances are referred to
as EJB objects.
- Primary key -- One or more variables that uniquely
identify a specific entity bean instance. A primary key that consists
of a single variable of a primitive Java data type can be specified at
deployment. A primary key class is used to encapsulate
primary keys that consist of multiple variables or more complex Java data
types. The primary key class also contains methods to create primary
key objects and manipulate those objects.
Figure 3. The components of an entity bean
Entity beans encapsulate and manipulate persistent (or permanent)
business data. For example, at a bank, entity beans can be used to
model customer profiles, checking and savings accounts, car loans, mortgages,
and customer transaction histories.
To ensure that this important data is not lost, the entity bean stores its
data in a data source such as a database. When the data in an
enterprise bean instance is changed, the data in the data source is
synchronized with the bean data. Of course, this synchronization takes
place within the context of the appropriate type of transaction, so that if a
router goes down or a server fails, permanent changes are not lost.
When you design an entity bean, you must decide whether you want the
enterprise bean to handle this data synchronization or whether you want the
container to handle it. An enterprise bean that handles its own data
synchronization is said to implement bean-managed persistence
(BMP), while an enterprise bean whose data synchronization is handled by the
container is said to implement container-managed persistence
(CMP).
Unless you have a good reason for implementing BMP, it is recommended that
you design your entity beans to use CMP. You must use entity beans with
BMP if you want to use a data source that is not supported by the EJB
server. The code for an enterprise bean with CMP is easier to write and
does not depend on any particular data storage product, making it more
portable between EJB servers.
This section discusses the basics of session beans.
Every session bean must have the following components, which are illustrated
in Figure 4:
- Bean class--This class encapsulates the data associated
with the session bean and contains the developer-implemented business methods
that access this data. It also contains the methods used by the
container to manage the life cycle of an session bean instance. EJB
clients (whether they are other enterprise beans or user applications)
never access objects of this class directly; instead, they use
the container-generated classes associated with the home and remote interfaces
to manipulate the session bean.
- Home interface--This interface defines the methods used by
the client to create and remove instances of the session bean. This
interface is implemented by the container during deployment in a class known
generically as the EJB home class; instances are referred to
as EJB home object.
- Remote interface--After the client has used the home
interface to gain access to an session bean, it uses this interface to invoke
indirectly the business methods implemented in the bean class. This
interface is implemented by the container during deployment in a class known
generically as the EJB object class; instances are referred to
as EJB objects.
Unlike an entity bean, a session bean does not have a primary key
class. A session bean does not require a primary key class because you
do not need to search for specific instances of session beans.
Figure 4. The components of a session bean
Session beans encapsulate data and methods associated with a user session,
task, or ephemeral object. By definition, the data in a session bean
instance is ephemeral; if it is lost, no real harm is done. For
example, at a bank, a session bean represents a funds transfer, the creation
of a customer profile or new account, and a withdrawal or deposit. If
information about a fund transfer is already typed (but not yet committed),
and a server fails, the balances of the bank accounts remains the same.
Only the transfer data is lost, which can always be retyped.
The manner in which a session bean is designed determines whether its data
is shorter lived or longer lived:
- If a session bean needs to maintain specific data across methods, it is
referred to as a stateful session bean. When a session bean
maintains data across methods, it is said to have a conversational
state. A Web-based shopping cart is a classic use of a stateful
session bean. As the shopping cart user adds items to and subtracts
items from the shopping cart, the underlying session bean instance must
maintain a record of the contents of the cart. After a particular EJB
client begins using an instance of a stateful session bean, the client must
continue to use that instance as long as the specific state of that instance
is required. If the session bean instance is lost before the contents
of the shopping cart are committed to an order, the shopper must load a new
shopping cart.
- If a session bean does not need to maintain specific data across methods,
it is referred to as a stateless session bean. The example
Transfer session bean developed in Developing session beans provides an example of a stateless session bean. For
stateless session beans, a client can use any instance to invoke any of the
session bean's methods because all instances are the same.
The last step in the development of an enterprise bean is the creation of an
EJB module. An EJB module consists of the following:
- One or more deployable enterprise beans.
- A deployment descriptor, stored in an Extensible Markup Language (XML)
file. This file contains information about the structure and external
dependencies of the beans in the module, and application assembly information
describing how the beans are to be used in an application.
The EJB module can be created by using the tools within an integrated
development environment (IDE) like IBM's VisualAge for Java Enterprise
Edition or by using the tools contained in WebSphere. For more
information, see Tools for developing and deploying enterprise beans in the EJB server (AE) environment.
For information about packaging enterprise beans for the EJB server (CB)
environment, see Creating an EJB JAR file for an enterprise bean .
The EJB module is used to assemble enterprise beans into a single
deployable unit; this file uses the standard Java archive file
format. The EJB module can contain individual enterprise beans or
multiple enterprise beans. For more information, see Creating an EJB module and deployment descriptor.
The EJB module contains one or more deployable enterprise beans and one
deployment descriptor. The deployment descriptor contains
attribute and environment settings for each bean in the module, and it defines
how the container invokes functionality for all beans in the module.
The deployment descriptor attributes can be set for the entire enterprise bean
or for the individual methods in the bean. The container uses the
definition of the bean-level attribute unless a method-level attribute is
defined, in which case the latter is used.
The deployment descriptor contains the following information about entity and
session beans. These attributes can be set on the bean only; they
cannot be set on a specific method of the bean.
- The bean's name, class, home interfaces, remote interfaces, and bean
type (entity or session).
- Primary key class attribute--Identifies the primary key
class for the bean. For more information, see Writing the primary key class (entity with CMP) or Writing or selecting the primary key class (entity with BMP).
- Persistence management. Specifies whether persistence
management is performed by the enterprise bean or by the container.
- Container-managed fields attribute--Lists those persistent
variables in the bean class that the container must synchronize with fields in
a corresponding data source to ensure that this data is persistent and
consistent. For more information, see Defining variables.
- Reentrant attribute--Specifies whether an enterprise bean
can invoke methods on itself or call another bean that invokes a method on the
calling bean. Only entity beans can be reentrant. For more
information, see Using threads and reentrancy in enterprise beans.
- State management attribute--Defines the conversational
state of the session bean. This attribute must be set to either
STATEFUL or STATELESS. For more information on the meaning of these
conversational states, see Stateless versus stateful session beans.
- Timeout attribute--Defines the idle timeout value in
seconds associated with this session bean. (This attribute is an
extension to the standard deployment descriptor.)
- Settings for environment variables.
- References to external resources, such as resource factories, to the homes
of other enterprise beans, and to security roles.
The deployment descriptor contains the following application assembly
information:
- An application name and icons for identifying the module.
- The location of class files needed for a client program to access the
beans in the module.
- Security roles-- Define a group of permissions that a
given type of user must have in order to successfully use an
application. Roles represent a type of user that has the same access
rights to an application.
- Method permissions--Define a permission to invoke a
specified group of methods of an enterprise bean's home and remote
interfaces. This value is set per method.
- Transaction attributes--Define the transactional manner in
which the container invokes a method for enterprise beans that require
container-managed transaction demarcation. This value is set per
method. The values for this attribute are described in Enabling transactions and security in enterprise beans.
- Transaction isolation level attribute--Defines the degree
to which transactions are isolated from each other by the container.
This value is set per method. The values for this attribute are
described in Enabling transactions and security in enterprise beans. (This attribute is an extension to the standard
deployment descriptor.)
- RunAsMode and RunAsIdentity attributes--The
RunAsMode attribute defines the identity used to invoke the
method. If a specific identity is required, the
RunAsIdentity attribute is used to specify that identity.
This value is set per bean. The values for the RunAsMode
attribute are described in Enabling transactions and security in enterprise beans. (This attribute is an extension to the standard
deployment descriptor.)
The following binding attribute is stored in the repository (it is not part
of the deployment descriptor):
- JNDI home name attribute--Defines the Java Naming and
Directory Interface (JNDI) home name that is used to locate instances of an
EJB home object. This value is set per bean. The values for this
repository attribute are described in Creating and getting a reference to a bean's EJB object.
When you deploy an EJB module, the deployment tool creates or incorporates the
following elements:
- The container-implemented EJBObject and EJBHome
classes (hereafter referred to as the EJB object and EJB home classes) from
the enterprise bean's home and remote interfaces (and the persistor and
finder classes for entity beans with CMP).
- The stub and skeleton files required for remote method invocation
(RMI).
Figure 5 shows a simplified version of a deployed entity bean.
Figure 5. The major components of a deployed entity bean
You can deploy an EJB module with a variety of different tools. For
more information, see Tools for developing and deploying enterprise beans in the EJB server (AE) environment or Tools for developing and deploying enterprise beans in the EJB server (CB) environment.
To create EJB applications, create the enterprise beans and EJB clients that
encapsulate your business data and functionality and then combine them
appropriately. Figure 6 provides a conceptual illustration of how EJB applications
are created by combining one or more session beans, one or more entity beans,
or both. Although individual entity beans and session beans can be used
directly in an EJB client, session beans are designed to be associated with
clients and entity beans are designed to store persistent data, so most EJB
applications contain session beans that, in turn, access entity beans.
Figure 6. Conceptual view of EJB applications
This section provides an example of the ways in which enterprise beans can
be combined to create EJB applications.
If you develop EJB applications for the banking industry, you can develop the
following entity beans to encapsulate your business data and associated
methods:
- Account bean--An entity bean that contains information about customer
checking and savings accounts.
- CarLoan bean--An entity bean that contains information about an
automobile loan.
- Customer bean--An entity bean that contains information about a
customer, including information on accounts held and loans taken out by the
customer.
- CustomerHistory bean--An entity bean that contains a record of
customer transactions for specified accounts.
- Mortgage bean--An entity bean that contains information about a home
or commercial mortgage.
An EJB client can directly access entity beans or session beans;
however, the EJB Specification suggests that EJB clients use session beans to
in turn access entity beans, especially in more complex applications.
Therefore, as an EJB developer for the banking industry, you can create the
following session beans to represent client tasks:
- LoanApprover bean--A session bean that allows a loan to be approved
by using instances of the CarLoan bean, the Mortgage bean, or both.
- CarLoanCreator bean--A session bean that creates a new instance of a
CarLoan bean.
- MortgageCreator bean--A session bean that creates a new instance of a
Mortgage bean.
- Deposit bean--A session bean that credits a specified amount to an
existing instance of an Account bean.
- StatementGenerator bean--A session bean that generates a statement
summarizing the activities associated with a customer's accounts by using
the appropriate instances of the Customer and CustomerHistory entity
beans.
- Payment bean--A session bean that credits a payment to a
customer's loan by using instances of the CarLoan bean, the Mortgage
bean, or both.
- NewAccount bean--A session bean that creates a new instance of an
Account bean.
- NewCustomer bean--A session bean that creates a new instance of a
Customer bean.
- LoanReviewer bean--A session bean that accesses information about a
customer's outstanding loans (instances of the CarLoan bean, the Mortgage
bean, or both).
- Transfer bean--A session bean that transfers a specified amount
between two existing instances of an Account bean.
- Withdraw bean--A session bean that debits a specified amount from an
existing instance of an Account bean.
This example is simplified by necessity. Nevertheless, by using this
set of enterprise beans, you can create a variety of EJB applications for
different types of users by combining the appropriate beans within that
application. One or more EJB clients can then be built to access the
application.
When using beans built to the Sun Microsystems JavaBeans(TM) Specification
(as opposed to the EJB Specification), you combine predefined components such
as buttons and text fields to create GUI applications. When using
enterprise beans, you combine predefined components such as the banking beans
to create three-tiered applications.
For example, you can use the banking enterprise beans to create the
following EJB applications:
- Home Banking application--An Internet application that allows a
customer to transfer funds between accounts (with the Transfer bean), to make
payments on a loan by using funds in an existing account (with the Payment
bean), to apply for a car loan or home mortgage (with the CarLoanCreator bean
or the MortgageCreator bean).
- Teller application--An intranet application that allows a teller to
create new customer accounts (with the NewCustomer bean and the NewAccount
bean), transfer funds between accounts (with the Transfer bean), and record
customer deposits and withdrawals (with the Withdraw bean and the Deposit
bean).
- Loan Officer application--An intranet application that allows a loan
officer to create and approve car loans and home mortgages (with the
CarLoanCreator, MortgageCreator, LoanReviewer, and LoanApprover beans).
- Statement Generator application--A batch application that prints
monthly customer statements related to account activity (with the
StatementGenerator bean).
These examples represent only a subset of the possible EJB applications
that can be created with the banking beans.
After an enterprise bean is deployed into a container, clients can create and
use instances of that bean as required. Within the container, instances
of an enterprise bean go through a defined life cycle. The events in an
enterprise bean's life cycle are derived from actions initiated by either
the EJB client or the container in the EJB server. You must understand
this life cycle because for some enterprise beans, you must write some of the
code to handle the different events in the enterprise bean's life
cycle.
The methods mentioned in this section are discussed in greater detail in Developing enterprise beans.
This section describes the life cycle of a session bean instance.
Differences between stateful and stateless session beans are noted.
A session bean's life cycle begins when a client invokes a create method
defined in the bean's home interface. In response to this method
invocation, the container does the following:
- Creates a new memory object for the session bean instance.
- Invokes the session bean's setSessionContext method. (This
method passes the session bean instance a reference to a session context
interface that can be used by the instance to obtain container services and
get information about the caller of a client-invoked method.)
- Invokes the session bean's ejbCreate method corresponding to the
create method called by the EJB client.
After a session bean instance is created, it moves to the ready state of its
life cycle. In this state, EJB clients can invoke the bean's
business methods defined in the remote interface. The actions of the
container at this state are determined by whether a method is invoked
transactionally or nontransactionally:
- Transactional method invocations--When a client invokes a
transactional business method, the session bean instance is associated with a
transaction. After a bean instance is associated with a transaction, it
remains associated until that transaction completes. (Furthermore, an
error results if an EJB client attempts to invoke another method on the same
bean instance if invoking that method causes the container to associate the
bean instance with another transaction or with no transaction.)
The container then invokes the following methods:
- The afterBegin method, if that method is implemented by the bean
class.
- The business method in the bean class that corresponds to the business
method defined in the bean's remote interface and called by the EJB
client.
- The bean instance's beforeCompletion method, if that method is
implemented by the bean class and if a commit is requested prior to the
container's attempt to commit the transaction.
The transaction service then attempts to commit the transaction, resulting
either in a commit or a roll back. When the transaction completes, the
container invokes the bean's afterCompletion method, passing the
completion status of the transaction (either commit or rollback).
If a rollback occurs, a stateful session bean can roll back its
conversational state to the values contained in the bean instance prior to
beginning the transaction. Stateless session beans do not maintain a
conversational state, so they do not need to be concerned about
rollbacks.
- Nontransactional method invocations--When a client invokes
a nontransactional business method, the container simply invokes the
corresponding method in the bean class.
The container has a sophisticated algorithm for managing which enterprise bean
instances are retained in memory. When a container determines that a
stateful session bean instance is no longer required in memory, it invokes the
bean instance's ejbPassivate method and moves the bean instance into a
reserve pool. A stateful session bean instance cannot be passivated
when it is associated with a transaction.
If a client invokes a method on a passivated instance of a stateful session
bean, the container activates the instance by restoring the instance's
state and then invoking the bean instance's ejbActivate method.
When this method returns, the bean instance is again in the ready
state.
Because every stateless session bean instance of a particular type is the
same as every other instance of that type, stateless session bean instances
are not passivated or activated. These instances exist in a ready state
at all times until their removal.
A session bean's life cycle ends when an EJB client or the container
invokes a remove method defined in the bean's home interface and remote
interface. In response to this method invocation, the container calls
the bean instance's ejbRemove method.
If you attempt to remove a bean instance while it is associated with a
transaction, the javax.ejb.RemoveException is thrown.
After a bean instance is removed, any attempt to invoke a method on that
instance causes the java.rmi.NoSuchObjectException to be
thrown.
A container can implicitly call a remove method on an instance after the
lifetime of the EJB object has expired. The lifetime of a session EJB
object is set in the deployment descriptor with the timeout
attribute.
For more information on the remove methods, see Removing a bean's EJB object.
This section describes the life cycle of entity bean instances.
Differences between entity beans with CMP and BMP are noted.
An entity bean instance's life cycle begins when the container creates
that instance. After creating a new entity bean instance, the container
invokes the instance's setEntityContext method. This method passes
the bean instance a reference to an entity context interface that can be used
by the instance to obtain container services and get information about the
caller of a client-invoked method.
After an entity bean instance is created, it is placed in a pool of available
instances of the specified entity bean class. While the instance is in
this pool, it is not associated with a specific EJB object. Every
instance of the same enterprise bean class in this pool is identical.
While an instance is in this pooled state, the container can use it to invoke
any of the bean's finder methods.
When a client needs to work with a specific entity bean instance, the
container picks an instance from the pool and associates it with the EJB
object initialized by the client. An entity bean instance is moved from
the pooled to the ready state if there are no available instances in the ready
state.
There are two events that cause an entity bean instance to be moved from
the pooled state to the ready state:
- When a client invokes the create method in the bean's home interface
to create a new and unique entity of the entity bean class (and a new record
in the data source). As a result of this method invocation, the
container calls the bean instance's ejbCreate and ejbPostCreate methods,
and the new EJB object is associated with the bean instance.
- When a client invokes a finder method to manipulate an existing instance
of the entity bean class (associated with an existing record in the data
source). In this case, the container calls the bean instance's
ejbActivate method to associate the bean instance with the existing EJB
object.
When an entity bean instance is in the ready state, the container can
invoke the instance's ejbLoad and ejbStore methods to synchronize the
data in the instance with the corresponding data in the data source. In
addition, the client can invoke the bean instance's business methods when
the instance is in this state. All interactions required to handle an
entity bean instance's business methods in the appropriate transactional
(or nontransactional) manner are handled by the container.
When a container determines that an entity bean instance in the ready state
is no longer required, it moves the instance to the pooled state. This
transition to the pooled state results from either of the following
events:
- When the container invokes the ejbPassivate method.
- When the EJB client invokes a remove method on the EJB object or on the
EJB home object. When one of these methods is called, the underlying
entity is removed permanently from the data source.
An entity bean instance's life cycle ends when the container invokes the
unsetEntityContext method on an entity bean instance in the pooled
state. Do not confuse the removal of an entity bean instance with the
removal of the underlying entity whose data is stored in the data
source. The former simply removes an uninitialized object; the
latter removes data from the data source.
For more information on the remove methods, see Removing a bean's EJB object.