Author: RAMU MEDA

Date: 01/sep/03

 

Enterprise Beans

  • Enterprise beans are server components written in the Java programming language.
  • Enterprise beans contain the business logic for your application.

Session Beans

  • A session bean represents a client in the J2EE server.
  • A session bean converses with the client, and can be thought of as an extension of the client.
  • Each session bean can have only one client.
  • When the client terminates, its corresponding session bean also terminates. Therefore, a session bean is transient, or non-persistent.

Entity Beans

  • An entity bean represents a business object in a persistent storage mechanism such as a database
  • might be stored as a row in the customer table of a relational database.
  • An entity bean's information does not have to be stored in a relational database. It could be stored in an object database, a legacy application, a file, or some other storage mechanism.
  • The persistence of an entity bean can be managed by either the entity bean itself, or by the EJB container.
  • Bean-managed persistence requires you to write the data access code in the Bean.
  • Container-managed persistence means that the EJB container handles the data access calls automatically.

Comparing Session and Entity Beans

 

Session Bean

Entity Bean

Purpose

Performs a task for a client.

Represents a business entity object that exists in persistent storage.

Shared
Access

May have one client.

May be shared by multiple clients.

Persistence

Not persistent. When the client terminates its session bean is no longer available.

Persistent. Even when the EJB container terminates, the entity state remains in a database.

 

 

Java BeansTM Components and Enterprise Beans

  • JavaBeans components and enterprise beans are not the same. Although both components are written in the Java programming language, they are not interchangeable.
  • JavaBeans components define a convention for making a Java class instance customizable by design tools, allowing the tools to link these customized objects via events.
  • Enterprise beans implement multi-user, transactional services.

Programming Restrictions for Enterprise Beans

To avoid conflicts with the services provided by container,, enterprise beans are restricted from performing certain operations:

  • Managing or synchronizing threads
  • Accessing files or directories with the java.io package
  • Using AWT functionality to display information or to accept information from a keyboard
  • Listening on a socket, accepting connections on a socket, or using a socket for multicast
  • Setting a socket factory used by ServerSocket, Socket, or the stream handler factory used by the URL class
  • Loading a native library

Database Access

         Both session and entity beans can access a database.

         include SQL calls in a session bean under the following circumstances:

         The application is relatively simple.

         The data returned by the SQL call will not be used by multiple clients.

         The data does not represent a business entity.

  • access a database from an entity bean if any of the following conditions are true:
      • More than one client will use the data returned by the database call.
      • The data represents a business entity.
      • You want to hide the relational model from the session bean.

 

 


Session Beans

         A session bean represents a single client inside the J2EE server.

         The client accesses remote services by invoking the session bean's methods.

         The session bean performs work for its client, shielding the client from complexity by executing business tasks inside the server.

         As its name suggests, a session bean is similar to an interactive session.

o        A session bean is not shared-- it may have just one client, in the same way that an interactive session may have just one user.

o        Like an interactive session, a session bean is not persistent.

o        When the client terminates, its session bean appears to terminate and is no longer associated with the client.

         Session beans are powerful because they extend the reach of your clients into remote servers-- yet they're easy to build. The following section shows you how to construct a simple session bean.

Session Bean Class

The session bean must meet these requirements:

  • It implements the SessionBean interface.
  • The class is defined as public.
  • The class cannot be defined as abstract or final.
  • It implements one or more ejbCreate methods.
  • It implements the business methods.
  • It contains a public constructor with no parameters.
  • It must not define the finalize method.

The SessionBean Interface

  • extends the EnterpriseBean interface, which in turn extends the Serializable interface.
  • The SessionBean interface declares the ejbRemove, ejbActivate, ejbPassivate, and setSessionContext methods.
  • The Bean class, but it must implement them because they're declared in the SessionBean interface.

The ejbCreate Methods

  • Because an enterprise bean runs inside an EJB container, a client cannot directly instantiate the bean.
  • Only the EJB container can instantiate an enterprise bean.
  • During instantiation, the example program performs these steps:
    • The client invokes a create method on the home object:
    • The EJB container instantiates the enterprise bean.
    • The EJB container invokes the appropriate ejbCreate method Typically, an ejbCreate method initializes the state of the enterprise bean.
    • An enterprise bean may have one or more ejbCreate methods. The signatures of the methods meet the following requirements:
      • The access control modifier must be public.
      • The return type must be void.
      • The arguments must be legal types for Java RMI.
      • The modifier cannot be static or final.
      • The throws clause may include the javax.ejb.CreateException and other exceptions that are specific to your application. The ejbCreate method usually throws a CreateException if an input parameter is invalid.

Business Methods

         The primary purpose of a session bean is to run business tasks for the client.

         The client invokes business methods on the remote object reference that is returned by the create method.

         From the client's perspective, the business methods appear to run locally, but they actually run remotely in the session bean.

         The signature of a business method must conform to these rules:

         The method name must not conflict with one defined by the EJB architecture. For example, you cannot call a business method ejbCreate or ejbActivate.

         The access control modifier must be public.

         The arguments and return types must be legal types for Java RMI.

         The modifier must not be static or final.

         The throws clause may include exceptions that you define for your application. The removeBook method, for example, throws the BookException if the book is not in the cart.

         To indicate a system-level problem, such as the inability to connect to a database, a business method should throw the javax.ejb.EJBException. When a business method throws an EJBException, the container wraps it in a RemoteException, which is caught by the client.

         The container will not wrap application exceptions.

         Because EJBException is a subclass of RuntimeException, you do not need to include it in the throws clause of the business method.

Home Interface

  • A home interface extends the EJBHome interface.
  • The purpose of the home interface is to define the create methods that a client may invoke.
  • Every create method in the home interface corresponds to an ejbCreate method in the bean class.
  • The signatures of the ejbCreate and create methods are similar, but differ in important ways. The rules for defining the signatures of the create methods of a home interface follow:
    • The number and types of argments in a create method must match those of its corresponding ejbCreate method.
    • The arguments and return type of the create method must be valid RMI types.
    • A create method returns the remote interface type of the enterprise bean. (But an ejbCreate method returns void.)
    • The throws clause of the create method must include the java.rmi.RemoteException and the javax.ejb.CreateException.

Remote Interface

         The remote interface, which extends javax.ejb.EJBObject, defines the business methods that a client may invoke. 
         The method definitions in a remote interface must follow these rules: 
o        Each method in the remote interface must match a method implemented in the enterprise bean class.
o        The signatures of the methods in the remote interface must be identical to the signatures of the corresponding methods in the enterprise bean class.
o        The arguments and return values must be valid RMI types.
o        The throws clause must include the java.rmi.RemoteException.

State Management Modes

When you specify the deployment descriptor of a session bean, you must choose between two state management modes: stateful or stateless.

 

 

Stateful Session Beans

         The state is retained for the duration of the client-bean session.

         When the client removes the bean, the session ends and the state disappears.

         This transient nature of the state is not a problem, however, because when the conversation between the client and the bean is over there is no need to retain the state.

Stateless Session Beans

  • A stateless session bean does not maintain a conversational state for a particular client.
  • When a client invokes the method of a stateless bean, the beans's instance variables may contain a state, but only for the duration of the invocation.
  • When the method is finished, the state is no longer retained.
  • Except during method invocation, all instances of a stateless bean are equivalent, allowing the EJB container to assign an instance to any client.

         Because stateless session beans can support multiple clients, they can offer better scalability for applications that require large numbers of clients.

         Typically, an application requires fewer stateless session beans than stateful session beans to support the same number of clients.

         At times, the EJB container may write a stateful session bean out to secondary storage. However, stateless session beans are never written out to secondary storage. Therefore, stateless beans may offer better performance than stateful beans.

         The home interface of a stateless session bean must have a single create method with no arguments.

         The session bean class must contain one ejbCreate method, also without arguments. (The arguments are only needed by stateful session beans, which use them to initialize their states.)

Choosing Between Stateful and Stateless Session Beans

consider using a stateful session bean if any of the following conditions are true:

         The bean's state must be initialized when it is created.

         The bean needs to hold information about the client across method invocations.

         The client is an interactive application.

use stateless session beans:

         The bean performs a task that is not tailored to the needs of a particular client. For example, you might use a stateless session bean to fetch from a database a commonly used set of data.

         The bean doesn't need to hold information about the client across method invocations.

The Life Cycle of a Session Bean

  • The life cycle is managed by the EJB container, not by your applications.

The Stateful Session Bean Life Cycle

  • 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.
  • 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 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 Stateless Session Bean Life Cycle

  • Because a stateless session bean is never passivated, its life cycle has just two stages: non-existent and ready for the invocation of business methods.

FIGURE 3-2 Life Cycle of a Stateless Session Bean

Comparing Session Beans

  • A client can determine if the object references of two stateful session beans are identical by invoking the isIdentical method:
bookCart = home.create("Bill Shakespeare"); 
videoCart = home.create("Lefty Lee");
. . .
if (bookCart.isIdentical(bookCart)) { 
// true . . . }
if (bookCart.isIdentical(videoCart)) { 
// false . . . }
         Because stateless session beans have the same object identity, the isIdentical method always returns true when used to compare two such beans. 

Passing a Session Bean's Object Reference

  • You can't pass the this reference, to pass a reference to itself, to another bean because the session bean is not a remote object.
  • Instead, your bean must pass an object reference for the instance. It gets the reference to itself by calling the getEJBObject method of the SessionContext interface

Accessing Environment Entries

  • Note: The material described in this section applies to both session and entity beans.

  • Stored in an enterprise bean's deployment descriptor, an environment entry is a name-value pair that allows you to customize the bean's business logic without changing its source code. An enterprise bean that calculates discounts, for example, might have an environment entry named "Discount Percent." Before deploying the bean's application, you could assign "Discount Percent" a value of .05 on the Environment tabbed pane of the Application Deployment Tool. When you run the application, the enterprise bean fetches the .05 value from its environment.
  • First, the method locates the environment naming context by invoking lookup with the "java:comp/env" parameter. Then it calls lookup on the environment to get the values for the "Discount Level" ..
 

 

 


Entity Beans

         An entity bean represents an entity kept in a persistent storage mechanism, usually a database.

         Inside the J2EE server, this application would represent the business entity objects with entity beans.

Characteristics of Entity Beans

  • Entity beans differ from session beans in several ways. Entity beans are persistent, allow shared access, and have primary keys.

Persistence

  • Because the state of an entity bean is saved in a storage mechanism, it is persistent.
  • Persistence means that the entity bean exists beyond the lifetime of the application or the J2EE server process.
  • There are two types of persistence: bean-managed and container-managed. You declare the persistence type with the Application Deployment Tool, which stores the information in the entity bean's deployment descriptor.
  • With bean-managed persistence, the entity bean code that you write contains the calls that access the database. The ejbCreate method, for example, will issue the SQL insert statement. You are responsible for coding the insert statement and any other necessary SQL calls.
  • If the container manages an entity bean's persistence, it automatically generates the necessary database access calls. For example, when a client creates an entity bean, the container generates a SQL insert statement. The code that you write for the entity bean does not include any SQL calls. The container also synchronizes the entity bean's instance variables with the data in the underlying database. These instance variables are often referred to as container-mananged fields.
  • You declare the container-managed fields with the Application Deployment Tool, which enters the list of fields in the deployment descriptor.
  • Container-managed persistence has two advantages over bean-managed persistence.
    • First, entity beans with container-managed persistence require less code.
    • Second, because the beans don't contain the database access calls, the code is independent of any particular data store, such as a relational database. However, container-managed persistence has several limitations.
  • Container-Managed Persistence limitations
    • The implementation of container-managed persistence for entity beans does not provide a full set of features for mapping objects to relational databases:
    • The entity bean class may be mapped to only one table in the database.
    • A container-managed field may be mapped to only one column in the table.
    • When the container loads the container-managed fields from the underlying database, it loads all of them. If the amount of data loaded is large, this approach may be inefficient because a business method may not need all of the container-managed fields.
    • If the container-managed fields of multiple entity beans map to the same data item in a database, and if these beans are invoked in the same transaction, they may see an inconsistent view of the data item.
    • The Application Deployment Tool generates SQL statements for the ejbCreate, ejbRemove, ejbLoad, and ejbStore methods. You may modify only the table and column names of these SQL statements. You may not modify the number and order of the question marks, which are place holders for the input parameters.
    • You cannot call stored procedures in the generated SQL statements.
    • In the "Create Table" SQL statement, you may change the SQL type of a table column provided that the SQL type is compatible with its corresponding instance variable.
    • The table and column names in all of the SQL statements must be consistent.
    • The generated SQL statements have been tested with these types of databases: Cloudscape, Oracle, and Microsoft SQL Server. You may need to edit the generated SQL statements to satisify the requirements of your database

Shared Access

  • Entity beans may be shared by multiple clients. Because the clients might want to change the same data, it's important that entity beans work within transactions.
  • Typically, the EJB container provides transaction management. You specify the transaction attributes in the bean's deployment descriptor. You do not have to code the transaction boundaries in the bean-- the container marks the boundaries for you.

Primary Key

  • Each entity bean has a unique object identifier. The unique identifier, or primary key, enables the client to locate a particular entity bean.

A Bean-Managed Persistence Example

Entity Bean Class

The entity bean class meets the requirements of every entity bean:

  • It implements the EntityBean interface.
  • The class is defined as public.
  • The class cannot be defined as abstract or final.
  • It implements zero or more ejbCreate and ejbPostCreate methods.
  • It implements the finder methods (only for bean-managed persistence).
  • It implements the business methods.
  • It contains an empty constructor.
  • It does not implement the finalize method.

The EntityBean Interface

  • The EntityBean interface extends the EnterpriseBean interface, which extends the Serializable interface.
  • The EntityBean interface declares a number of methods, such as ejbActivate and ejbLoad, which you must implement in your entity bean class.

The ejbCreate Method

  • When the client invokes a create method, the EJB container invokes the corresponding ejbCreate method.
  • Typically, an ejbCreate method in an entity bean performs the following tasks:
    • Inserts the entity state into the database.
    • Initializes the instance variables.
    • Returns the primary key.
  • an enterprise bean may contain multiple ejbCreate methods
  • When writing an ejbCreate method for an entity bean, be sure to follow these rules:
    • The access control modifier must be public.
    • The return type must be the primary key (only for bean-managed persistence).
    • The arguments must be legal types for Java RMI.
    • The method modifier cannot be final or static.
    • The throws clause may include the javax.ejb.CreateException and other exceptions that are specific to your application.
    • An ejbCreate method usually throws a CreateException if an input parameter is invalid.
    • If an ejbCreate method cannnot create an entity because another entity with the same primary key already exists, it should throw a javax.ejb.DuplicateKeyException (a subclass of CreateException).
    • If a client receives a CreateException or a DuplicateKeyException, it should assume that the entity was not created.
    • The state of an entity bean may be directly inserted into the database by a non-J2EE application. Although the entity bean for this row was not created by an ejbCreate method, the bean can be located by a client program.

The ejbPostCreate Method

  • For each ejbCreate method, you must write an ejbPostCreate method in the entity bean class.
  • The EJB container invokes ejbPostCreate immediately after it calls ejbCreate. Unlike the ejbCreate method, the ejbPostCreate method can invoke the getPrimaryKey and getEJBObject methods of the EntityContext interface
  • Often, your ejbPostCreate methods will be empty.
  • The signature of an ejbPostCreate must meet the following requirements:
    • The number and types of arguments must match a corresponding ejbCreate method.
    • The access control modifier must be public.
    • The method modifier cannot be final or static.
    • The return type must be void.
    • The throws clause may include the javax.ejb.CreateException, and other exceptions that are specific to your application.

The ejbRemove Method

  • A client removes an entity bean by invoking the remove method.
  • This invocation causes the EJB client to call the ejbRemove method, which deletes the entity state from the database.
  • If the ejbRemove method encounters a system problem, it should throw the javax.ejb.EJBException. If it encounters an application error, it should throw a javax.ejb.RemoveException.
  • An entity bean may also be removed directly by a database deletion.

The ejbLoad Method and ejbStore Methods

  • If the EJB container needs to synchronize the instance variables of an entity bean with the corresponding values stored in a database, it invokes the ejbLoad and ejbStore methods.
  • The ejbLoad method refreshes the instance variables from the database, and the ejbStore method writes the variables to the database.
  • The client may not call ejbLoad and ejbStore.
  • If a business method is associated with a transaction, the container invokes ejbLoad before the business method executes.
  • Immediately after the business method executes, the container calls ejbStore.
  • Because the container invokes ejbLoad and ejbStore, you do not have to refresh and store the instance variables in your business methods-- the container performs these functions for you.
  • If the ejbLoad and ejbStore methods cannot locate an entity in the underlying database, they should throw the javax.ejb.NoSuchEntityException. This exception is a subclass of EJBException. Because EJBException is a subclass of RuntimeException, you do not have to include it in the throws clause. When NoSuchEntityException is thrown, the EJB container wraps it in a RemoteException before returning it to the client.

The Finder Methods

         The finder methods allow clients to locate entity beans.
         For every finder method available to a client, the entity bean class must implement a corresponding method that begins with the prefix ejbFind.
         The finder methods specific to your application, such as ejbFindByLastName and ejbFindInRange, are optional, but the ejbFindByPrimaryKey method is required. As its name infers, the ejbFindByPrimaryKey method accepts as an argument the primary key, which it uses to locate an entity bean. 
         The ejbFindByPrimaryKey method may look strange to you, because it uses a primaryKey for both the method argument and return value. However, remember that the client does not call ejbFindByPrimaryKey directly. It is the EJB container that calls the ejbFindByPrimaryKey method. The client invokes the findByPrimaryKey method, which is defined in the home interface. 
         The following list summarizes the rules for the finder methods that you implement in an entity bean class with bean-managed persistence:
o        The ejbFindByPrimaryKey method must be implemented.
o        A finder method name must start with the prefix ejbFind.
o        The access control modifier must be public.
o        The method modifier cannot be final or static.
o        The arguments and return type must be legal types for Java RMI.
o        The return type must be the primary key or a collection of primary keys.
o        The throws clause may include the javax.ejb.FinderException, and other exceptions that are specific to your application. 
o        If a finder method returns a single primary key, it should throw the javax.ejb.ObjectNotFoundException if the requested entity does not exist. The ObjectNotFoundException is a subclass of FinderException. 
o        If a finder method returns a collection of primary keys, it should throw a FinderException. 

The Business Methods

  • The business methods contain the business logic that you want to encapsulate within the entity bean.
  • Usually, the business methods do not access the database, allowing you to separate business logic from the database access code.
  • The requirements for the signature of a business method are the same for both session and entity beans:
    • The method name must not conflict with a method name defined by the EJB architecture. For example, you cannot call a business method ejbCreate or ejbActivate.
    • The access control modifier must be public.
    • The method modifier cannot be final or static.
    • The arguments and return types must be legal types for Java RMI.
    • The throws clause may include the the exceptions that you define for your application. The debit method, for example, throws the InsufficientBalanceException. To indicate a system-level problem, a business method should throw the javax.ejb.EJBException.

Database Calls

SQL Statement in AccountEJB

Method

Resulting SQL Statement

ejbCreate

insert

ejbFindByPrimaryKey

select

ejbFindByLastName

select

ejbFindInRange

select

ejbLoad

select

ejbRemove

delete

ejbStore

update

 

Home Interface

  • The create methods in the home interface must conform to these requirements:
    • It has the same number and types of arguments as its matching ejbCreate method in the enterprise bean class.
    • It returns the remote interface type of the enterprise bean.
    • The throws clause includes the exceptions specified by the throws clause of the corresponding ejbCreate and ejbPostCreate methods.
    • The throws clause contains the java.rmi.RemoteException and the javax.ejb.CreateException.

         Every finder method in the home interface corresponds to a finder method in the entity bean class.

         The name of a finder method in the home interface begins with find, whereas the name of one in the entity bean class begins with ejbFind.

         The rules for defining the signatures of the finder methods of a home interface follow:

o        The number and types of arguments must match those of the corresponding method in the entity bean class.

o        The return type is the entity bean's remote interface type, or a collection of those types.

o        The exceptions in the throws clause include those of the corresponding method in the entity bean class.

o        The throws clause contains the javax.ejb.FinderException and the javax.ejb.RemoteException.

Remote Interface

o        The remote interface extends javax.ejb.EJBObject and defines the business methods that a client may invoke. 
o        The requirements for the method definitions in a remote interface are the same for both session and entity beans: 
o        Each method in the remote interface must match a method in the enterprise bean class.
o        The signatures of the methods in the remote interface must be identical to the signatures of the corresponding methods in the enterprise bean class.
o        The arguments and return values must be valid RMI types.
o        The throws clause must include java.rmi.RemoteException

 

A Container-Managed Persistence Example

  • The code in the home and remote interfaces is the same whether or not an entity bean uses container-managed persistence.
  • However, the code in the entity bean class is different for container-managed and bean-managed persistence. With container-managed persistence, the entity bean class contains no database access code. The Application Deployment Tool generates the SQL statements needed by the entity bean class. In order to generate the SQL statements, the tool needs to know which instance variables must be stored in the database. These instance variables are called container-managed fields.

Container-Managed Fields

  • These fields represent the state of an ProductEJB instance.
  • You specify the container-managed fields with the Application Deployment Tool
  • A container-managed field must be one of the following types:
    • Java serializable class
    • Java primitive
    • Reference of a home interface
    • Reference of a remote interface
    • A container-managed field must be public and may not be defined as transient.

The ejbCreate Method

  • The ejbCreate method initializes the container-managed fields from the input parameters.
  • The method returns null because with container-managed persistence the container ignores its return value.
  • After the ejbCreate method executes, the container inserts the container-manged fields into the database.

The ejbRemove Method

  • When the client invokes the remove method, the container calls the ejbRemove method.
  • After the ejbRemove method returns, the container deletes the row from the database.
  • If the container fails to delete the row, it throws an exception.
  • If an entity bean needs to perform some operation immediately before removal, it should do so in the ejbRemove method.

The ejbLoad Method

When the container needs to refresh the entity bean's state from the database, it performs these steps:

  • Selects the row from the database
  • Assigns the row's column values to the container-manged fields
  • Invokes the ejbLoad method
  • Usually, the ejbLoad method is empty. The entity bean may use the ejbLoad method, however, to transform the values read from the database. For example, the ejbLoad method might uncompress text data so that it can be manipulated by the business methods.

The ejbStore Method

When the container needs to save the entity bean's state in the database, it performs these steps:

  • Invokes the ejbStore method
  • Gets the values of the container-managed fields
  • Updates the row in the database with the values of the container-managed fields
  • Like the ejbLoad method, the ejbStore method is typically empty. But if you need to transform container-managed fields before the container stores them in the database, you should do so in the ejbStore method. For example, the ejbStore method might compress text data before the container stores it in the database.

Handling Exceptions

The exceptions thrown by enterprise beans fall into two categories: system and application.

         A system exception indicates a problem with the services that support an application.

o        Examples of these problems include the following: a database connection cannot be obtained, a SQL insert fails because the database is full, a lookup method cannot find the desired object.

o        If your enterprise bean encounters a sytem-level problem, it should throw a javax.ejb.EJBException. The container will wrap the EJBException in a RemoteException, which it passes back to the client.

o        Because the EJBException is a subclass of the RuntimeException, you do not have to specify it in the throws clause of the method declaration.

o        If a system exception is thrown, the EJB container might destroy the bean instance. Therefore, a system exception cannot be handled by the bean's client program; it requires intervention by a system administrator.

         An application exception signals an error in the business logic of an enterprise bean.

o        There are two types of application exceptions: customized and predefined.

o        A customized exception is one that you've coded yourself, such as the InsufficentBalanceException thrown by the debit business method of the AccountEJB example.

o        The javax.ejb package includes several predefined exceptions that are designed to handle common problems. For example, an ejbCreate method should throw a CreateException to indicate an invalid input parameter.

o        When an enterprise bean throws an application exception, the container does not wrap it in another exception. The client should be able to handle any application exception it receives.

o        If a system exception occurs within a transaction, the EJB container rolls back the transaction. However, if an application exception is thrown within a transaction, the container does not roll back the transaction.

The following table summarizes the exceptions of the javax.ejb package. All of these exceptions are application exceptions, except for the NoSuchEntityException and the EJBException, which are system exceptions.

Exceptions

Method Name

Exception It Throws

Reason for Throwing

ejbCreate

CreateException

An input parameter is invalid.

ejbFindByPrimaryKey
(and other finder methods)

ObjectNotFoundException
(subclass of FinderException)

The database row for the requested entity bean is cannot be found.

ejbRemove

RemoveException

The entity bean's row cannot be deleted from the database.

ejbLoad

NoSuchEntityException

The database row to be loaded cannot be found.

ejbStore

NoSuchEntityException

The database row to be updated cannot be found.

(all methods)

EJBException

A system problem has been encountered.

 

Primary Key Class

  • You specify the primary key class with the Application Deployment Tool.
  • When deploying the ProductEJB bean, for example, you would specify a java.lang.String as the primary key class.
  • In most cases, your primary key class will be a String or some other class that belongs to the java package.

Creating a Primary Key Class

  • For some entity beans, you will need to define your own primary key class.
  • if a primary key is composed of multiple fields then you must create a primary key class
  • Primary Class Requirements
    • The access control modifier of the class is public.
    • All fields are declared as public.
    • For container-managed persistence, the field names in the primary key clsss must match the corresponding container-managed fields in the entity bean class.
    • The class has a public default constructor.
    • The class implements the hashCode() and equals(Object other) methods.
    • The class is serializable.

Bean-Managed Persistence and the Primary Key Class

  • With bean-managed persistence, the ejbCreate method returns the primary key class:

Container-Managed Persistence and the Primary Key Class

  • For an entity bean with container-managed persistence, the ejbCreate method returns null. (With bean-managed persistence, it returns an instance of the primary key class.)
  • With container-managed persistence, you do not have to write the code for the ejbFindByPrimaryKey method.

Getting the Primary Key

         A client can fetch the primary key of an entity bean by invoking the getPrimaryKey method of the EJBObject class: account.getPrimaryKey();
         The entity bean retrieves its own primary key by calling the getPrimaryKey method of the context.getPrimaryKey(); 

 

The Life Cycle of an Entity Bean

  • The life cycle of an entity bean is controlled by the EJB container, not by your application
  • 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.
  • At the end of the life cycle, the EJB container removes the instance from the pool and invokes the unsetEntityContext method.

FIGURE 4-1 Life Cycle of an Entity Bean

         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 set the primary key.

         If the primary key is incorrect, the ejbLoad and ejbStore methods cannot synchronize the instance variables with the database.

         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.

 

 

Comparing Entity Beans

  • A client can determine if the object references of two entity beans are identical by invoking the isIdentical method:
Account accta, acctb;
. . .
if (accta.isIdentical(acctb))
 System.out.println("identical");
 

Or, the client can fetch and compare the primary keys of two entity beans:

String key1 = (String)accta.getPrimaryKey();
String key2 = (String)acctb.getPrimaryKey();
 
if (key1.compareTo(key2) == 0)
 System.out.println("equal");

Passing an Entity Bean's Object Reference

  • If you want to pass an entity bean to another bean, you can't pass the this reference. Instead, you must pass the entity bean's object reference by retrieve the object reference by calling getEJBObject on the EntityContext of an entity bean.

Transactions

  • Because the steps within a transaction are a unified whole, a transaction is often defined as an indivisible unit of work.
  • A transaction can end in two ways: with a commit or a rollback. When a transaction commits, the data modifications made by its statements are saved. If a statement within a transaction fails, the transaction rolls back, undoing the effects of all statements in the transaction.
  • the begin and commit statments mark the boundaries of the transaction. When deploying an enterprise bean, you determine how the boundaries are set by specifying either container-managed or bean-managed transactions.

## Container-Managed Transactions ##

  • In an enterprise bean with container-managed transactions, the EJB container sets the boundaries of the transactions.
  • You can use container-managed transactions with both session and entity beans.
  • Container-managed transactions simplify development because the enterprise bean code does not explicitly mark the transaction's boundaries.
  • The code does not include statements that begin and end the transaction.
  • Typically, the container begins a transaction immediately before an enterprise bean method starts. It commits the transaction just before the method exits. Each method can be associated with a single transaction.
  • Nested or multiple transactions are not allowed within a method.
  • Container-managed transactions do not require all methods to be associated with transactions. When deploying a bean, you specify which of the bean's methods are associated with transactions by setting the transaction attributes.

Transaction Attributes

  • A transaction attribute controls the scope of a transaction. Method-A of Bean 1 begins a transaction and then invokes method-B of Bean-2. When method-B executes, does it run within the scope of the transaction started by method-A or does it execute with a new transaction? The answer depends on the transaction attribute of method-B.

Transaction Attribute Values

A transaction attribute may have one of the following values:

  1. Required
  2. RequiresNew
  3. Mandatory
  4. NotSupported
  5. Supports
  6. Never

Required

    • If the client is running within a transaction and it invokes the enterprise bean's method, the method executes within the client's transaction.
    • If the client is not associated with a transaction, the container starts a new transaction before running the method.
    • The Required attribute will work for most transactions. Therefore, you may want to use it as a default, at least in the early phases of development. Because transaction attributes are declarative, you can easily change them at a later time.

RequiresNew

  • If the client is running within a transaction and it invokes the enterprise bean's method, the container takes the following steps:
    • suspends the client's transaction
    • starts a new transaction
    • delegates the call to the method
    • resumes the client's transaction after the method completes
  • If the client is not associated with a transaction, the container starts a new transaction before running the method.
  • You should use the RequiresNew attribute when you want to ensure that the method always runs within a new transaction.

Mandatory

  • If the client is running within a transaction and it invokes the enterprise bean's method, the method executes within the client's transaction.
  • If the client is not associated with a transaction, the container throws the TransactionRequiredException.
  • Use the Mandatory attribute if the enterprise bean's method must use the transaction of the client.

NotSupported

  • If the client is running within a transaction and it invokes the enterprise bean's method, the container suspends the client's transaction before invoking the method. After the method has completed, the container resumes the client's transaction.
  • If the client is not associated with a transaction, the container does not start a new transaction before running the method.
  • Use the NotSupported attribute when you want to ensure that the method will never run within a transaction generated by the container.

Supports

  • If the client is running within a transaction and it invokes the enterprise bean's method, the method executes within the client's transaction.
  • If the client is not associated with a transaction, the container does not start a new transaction before running the method.
  • Because the transactional behavior of the method may vary, you should use the Supports attribute with caution.

Never

  • If the client is running within a transaction and it invokes the enterprise bean's method, the container throws a RemoteException.
  • If the client is not associated with a transaction, the container does not start a new transaction before running the method.

Summary of Transaction Attributes

Table 6-1 summarizes the effects of the transaction attributes. Both the T1 and T2 transactions are controlled by the container. A T1 transaction is associated with the client that calls a method in the enterprise bean. In most cases, the client is another enterprise bean. A T2 transaction is started by the container just before the method executes.

In the last column, the word "none" means that the business method does not execute within a transaction controlled by the container. However, the database calls in such a business method might be controlled by the transaction manager of the DBMS.

 

Transaction Attributes and Scope

Transaction
Attribute

Client's
Transaction

Business Method's
Transaction

Required

none

T2

T1

T1

RequiresNew

none

T2

T1

T2

Mandatory

none

error

T1

T1

NotSupported

none

none

T1

none

Supports

none

none

T1

T1

Never

none

none

T1

error

 

 

Setting Transaction Attributes

  • Because transaction attributes are stored in the deployment descriptor, they can be changed during several phases of J2EE application development: enterprise bean creation, application assembly, and deployment.
  • However, as an enterprise bean developer, it is your responsibility to specify the attributes when creating the bean.
  • The attributes should be modified only by an application developer who is assembling components into larger applications.
  • Do not expect the person who is deploying the J2EE application to specify the transaction attributes.
  • You can specify the transaction attributes for the entire enterprise bean or for individual methods.
  • If you've specified one attribute for a method and another for the bean, the attribute for the method takes precedence.
  • When specifying attributes for individual methods, the requirements for session and entity beans vary. Session beans need the attributes defined for business methods, but do not allow them for the create methods. Entity beans require transaction attributes for the business, create, remove, and finder methods.

Rolling Back a Container-Managed Transaction

  • There are two ways to roll back a container-managed transaction.
    • First, if a system exception is thrown, the container will automatically roll back the transaction.
    • Second, by invoking the setRollbackOnly method of the EJBContext interface, the bean method instructs the container to roll back the transaction. If the bean throws an application exception, the roll back is not automatic, but may be initiated by a call to setRollbackOnly.
    • When the container rolls back a transaction, it always undoes the changes to data made by SQL calls within the transaction. However, only in entity beans will the container undo changes made to instance variables. (It does so by automatically invoking the entity bean's ejbLoad method, which loads the instance variables from the database.)
    • When a rollback occurs, a session bean must explicitly reset any instance variables changed within the transaction. The easiest way to reset a session bean's instance variables is by implementing the SessionSynchonization interface.

 

Synchronizing a Session Bean's Instance Variables

  • The SessionSynchonization interface, which is optional, allows you to synchronize the instance variables with their corresponding values in the database.
  • The container invokes the SessionSynchonization methods-- afterBegin, beforeCompletion, and afterCompletion-- at each of the main stages of a transaction.
  • The afterBegin method informs the instance that a new transaction has begun. The container invokes afterBegin immediately before it invokes the business method. The afterBegin method is a good place to load the instance variables from the database.
  • The container invokes the beforeCompletion method after the business method has finished, but just before the transaction commits. The beforeCompletion method is the last opportunity for the session bean to roll back the transaction (by calling setRollbackOnly). If it hasn't already updated the database with the values of the instance variables, the session bean may do so in the beforeCompletion method.
  • The afterCompletion method indicates that the transaction has completed. It has a single boolean parameter, whose value is true if the transaction was committed and false if it was rolled back. If a rollback occurred, the session bean can refresh its instance variables from the database in the afterCompletion method

Methods Not Allowed in Container-Managed Transactions

You should not invoke any method that might interfere with the transaction boundaries set by the container. The list of prohibited methods follows:

  • commit, setAutoCommit, and rollback methods of java.sql.Connection
  • getUserTransaction method of javax.ejb.EJBContext
  • any method of javax.transaction.UserTransaction

You may, however, use these methods to set boundaries in bean-managed transactions.

Bean-Managed Transactions

  • In a bean-managed transaction, the session bean code invokes methods that mark the boundaries of the transaction.
  • An entity bean may not have bean-managed transactions; it must use container-managed transactions instead.
  • Although beans with container-managed transactions require less coding, they have one limitation: When a method is executing, it can be associated with either a single transaction or no transaction at all. If this limitation will make coding your session bean difficult, you should consider using bean-managed transactions.

The following pseudo-code illustrates the kind of fine-grained control you can obtain with bean-managed transactions. By checking various conditions, the pseudo-code decides whether to start and stop different transactions within the business method.

begin transaction
...
update table-a
...
if (condition-x)
 commit transaction
else if (condition-y)
 update table-b
 commit transaction
else
 rollback transaction
 begin transaction
 update table-c
 commit transaction

When coding a bean-managed transaction, you must decide whether to use JDBC or JTA transactions. The sections that follow discuss the techniques and merits of both approaches.

JDBC Transactions

  • A JDBC transaction is controlled by the transaction manager of the DBMS.
  • You may want to use JDBC transactions when wrapping legacy code inside a session bean.
  • To code a JDBC transaction, you invoke the commit and rollback methods of the javax.sql.Connection interface.
  • The beginning of a transaction is implicit. A transaction begins with the first SQL statement that follows the most recent commit, rollback, or connect statement. (This rule is generally true, but may vary with DBMS vendor.)

The following code is from the WarehouseEJBexample, a session bean that uses the Connection interface's methods to delimit bean-managed transactions. The ship method starts by invoking setAutoCommit on the Connection object con. This invocation tells the DBMS not to automatically commit every SQL statement. Next, the ship method calls routines that update the order_item and inventory database tables. If the updates succeed, the transaction is committed. But if an exception is thrown, the transaction is rolled back.

public void ship (String productId, String orderId, int quantity) {
 
 try {
 con.setAutoCommit(false);
 updateOrderItem(productId, orderId);
 updateInventory(productId, quantity);
 con.commit();
 } catch (Exception ex) {
 try {
 con.rollback();
 throw new EJBException("Transaction failed: " +
 ex.getMessage());
 } catch (SQLException sqx) {
 throw new EJBException("Rollback failed: " +
 sqx.getMessage());
 }
 }
} 

JTA Transactions

  • JTA is the abbreviation for the Java Transaction API. This API allows you to demarcate transactions in a manner that is independent of the transaction manager implementation.
  • The J2EE SDK implements the transaction manager with the Java Transaction Service (JTS). But your code doesn't call the JTS methods directly. Instead, it invokes the JTA methods, which then call the lower-level JTS routines.
  • A JTA transaction is controlled by the J2EE transaction manager. You may want to use a JTA transaction because it can span updates to multiple databases from different vendors. A particular DBMS's transaction manager may not work with heterogenous databases. However, the J2EE transaction manager does have one limitation-- it does not support nested transactions. (It cannot start a transaction for an instance until the previous transaction has ended.)
  • To demarcate a JTA transaction, you invoke the begin, commit, and rollback methods of the UserTransaction interface.
  • The following code, taken from the TellerEJB example program, demonstrates the UserTransaction methods. The begin and commit invocations delimit the updates to the database. If the updates fail, the code invokes the rollback method and throws an EJBException.
public void withdrawCash(double amount) {
 
 UserTransaction ut = context.getUserTransaction();
 
 try {
 ut.begin();
 updateChecking(amount);
 machineBalance -= amount;
 insertMachine(machineBalance);
 ut.commit();
 } catch (Exception ex) {
 try {
 ut.rollback();
 } catch (SystemException syex) {
 throw new EJBException
 ("Rollback failed: " + syex.getMessage());
 }
 throw new EJBException 
("Transaction failed: " + ex.getMessage());
 }
}

Returning Without Committing

  • In a stateless session bean with bean-managed transactions, a business method must commit or roll back a transaction before returning. However, a stateful session bean does not have this restriction.
  • In a stateful session bean with a JTA transaction, the association between the bean instance and the transaction is retained across multiple client calls. Even if each business method called by the client opens and closes the database connection, the association is retained until the instance completes the transaction.
  • In a stateful session bean with a JDBC transaction, the JDBC connection retains the association between the bean instance and the transaction across multiple calls. If the connection is closed, the association is not retained.

Methods Not Allowed in Bean-Managed Transactions

  • Do not invoke the getRollbackOnly and setRollbackOnly methods of the EJBContext interface. These methods should be used only in container-managed transactions.
  • For bean-managed transactions you invoke the the getStatus and rollback methods of the UserTransaction interface.

Summary of Transaction Options

The decision tree in figure 6-2 shows the different approaches to transaction management that you may take.

 

  • Your first choice depends on whether the enterprise bean is an entity or a session bean. An entity bean must use container-managed transactions.
  • With container-managed transactions, you specify the transaction attributes in the deployment descriptor and you roll back a transaction with the setRollbackOnly method of the EJBContext interface.
  • A session bean may have either container-managed or bean-managed transactions. There are two types of bean-managed transactions: JDBC and JTA transactions. You delimit JDBC transactions with the commit and rollback methods of the Connection interface. To demarcate JTA transactions, you invoke the begin, commit, and rollback methods of the UserTransaction interface.
  • In a session bean with bean-managed transactions, it is possible to mix JDBC and JTA transactions. This practice is not recommended, however, because it could make your code difficult to debug and maintain.
  • If you're unsure about how to set up transactions in an enterprise bean, here's a tip: In the deployment descriptor specify container-managed transactions. Then, set the Required transaction attribute for the entire bean. This approach will work most of the time.

FIGURE ; Options in Specifying Transactions

Transaction Timeouts

  • For container-managed transactions, you control the transaction timeout interval by setting the value of the transaction.timeout property in the config/default.properties file. For example, you would set the timeout value to 5 seconds as follows: transaction.timeout=5 With this setting, if the transaction has not completed within 5 seconds, the EJB container manager rolls it back.
  • When J2EE is first installed, the timeout value is set to 0:

transaction.timeout=0

If the value is 0, the transaction will not time out.

  • Only enterprise beans with container-managed transactions are affected by the transaction.timeout property. For enterprise beans with bean-managed, JTA transactions, you invoke the setTransactionTimeout method of the UserTransaction interface.

Isolation Levels

  • Transactions not only ensure the full completion (or rollback) of the statements that they enclose, they also isolate the data modified by the statements.
  • The isolation level describes the degree to which the data being updated is visible to other transactions.
  • If the transaction allows other programs to read uncommitted data, performance may improve because the other programs don't have to wait until the transaction ends. But there's a tradeoff-- if the transaction rolls back, another program might read the wrong data.
  • You cannot modify the isolation level of a entity beans with container-managed persistence. These beans use the default isolation level of the DBMS, which is usually READ_COMMITTED.
  • For entity beans with bean-managed persistence and for all session beans, you can set the isolation level programmatically with the API provided by the underlying DBMS. A DBMS, for example, might allow you to permit uncommitted reads by invoking the setTransactionIsolation method: Connection con; ... con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);
  • Do not change the isolation level in the middle of a transaction. Usually, such a change causes the DBMS software to issue an implicit commit. Because the isolation levels offered by DBMS vendors may vary, you should check the DBMS documentation for more information.

 

Updating Multiple Databases

  • The J2EE transaction manager controls all enterprise bean transactions except for bean-managed JDBC transactions.
  • The J2EE transaction manager allows an enterprise bean to update multiple databases within a transaction. The figures that follow show two scenarios for updating multiple databases in a single transaction.

In figure 6-3, the client invokes a business method in Bean-A. The business method begins a transaction, updates Database-X, updates Database-Y, and invokes a business method in Bean-B. The second business method updates Database-Z and returns control to the the business method in Bean-A, which commits the transaction. All three database updates occur in the same transaction.

FIGURE 6-3 Updating Multiple Databases

In figure 6-4, the client calls a business method in Bean-A, which begins a transaction and updates Database-X. Then, Bean-A invokes a method in Bean-B, which resides in a remote J2EE server. The method in Bean-B updates Database-Y. The transaction managers of the J2EE servers ensure that both databases are updated in the same transaction.

FIGURE 6-4 Updating Multiple Databases Across J2EE Servers


Security


         You declare the security attributes of an enterprise bean in with the Application Deployment Tool.

         This declarative approach to security enforcement has two major advantages.

o        First, you save time because you don't have to code and debug security routines in your enterprise beans or their clients.

o        Second, the administrator of the J2EE server can customize the security attributes for a particular production environment at deployment time.

         The J2EE server enforces security at two levels: Authentication and Authorization.

Authentication

         Authentication is the process by which a user proves his or her identity to a system.

         The J2EE server controls client access with a distributed authentication service.

         This service controls whether or not a J2EE user can access the components within a J2EE application.

         In a commercial implementation of J2EE, for example, a J2EE user and an operating system user might be the same, but in the J2EE SDK they are not.

J2EE Users, Realms, and Groups

         A J2EE user is similar to an operating system user. Typically, both types of users represent people. However, these two types of users are not the same.

         The J2EE authentication service has no knowledge of the user and password you provide when logging on to the operating system.

         The J2EE authentication service is not connected to the security mechanism of the operating system. The two security services manage users that belong to different realms.

         A realm is a collection of users that are controlled by the same authentication policy. The J2EE authentication service governs users in two realms: certificate and default.

         Certificates are used with the HTTPS protocol to authenticate Web browser clients

         To verify the identity of a user in the certificate realm, the authentication service verifies a X509 certificate. The common name field of the X509 certificate is used as the principal name.

         In most cases, the J2EE authentication service verifies user identity by checking the default realm. This realm is used for the authentication of all clients except for Web browser clients that use the HTTPS protocol and certificates.

         A J2EE user of the default realm may belong to J2EE group. (A user in the certificate realm may not.)

         A group is a category of users, classified by common traits such as job title or customer profile. For example, most customers of an e-commerce application might belong to the CUSTOMER group, but the big spenders would belong to the PREFERRED group.

         Categorizing users into groups makes it easier to control the access of large numbers of users. A later section, Authorization, discusses controlling user access to enterprise beans.

Client Authentication

  • The J2EE authentication service controls access from all types of bean clients:
    • J2EE application clients,
    • stand-alone Java applications, and
    • web components.
  • When a J2EE application client starts running, its container pops open a window that requests the J2EE user name and password. The authentication service verifies that the user name and password from the log-on window exist in the default realm. After authentication, the user's security context is associated with any call that the client makes to enterprise beans deployed in the J2EE server.
  • Most of the examples in this book feature clients that are stand-alone Java applications. Because these clients do not log on, they are assigned the unauthenticated and anonymous user named guest. (The password is guest123.)
  • Other types of clients, including Web browsers, may also access the J2EE server without authentication. Such clients are always assigned the user guest, indicating that their access in unauthenticated.
  • Many applications do not require authentication. For example, an online product catalog would not force customers to log on if they are merely browsing. Also, when you first start developing an application, you may find it convenient to allow anyone (guest) to access the application's components.
  • During deployment, you specify whether or not a web component is a protected resource. If the web component is unprotected, anyone may access it from their browser. If an unprotected web component accesses an enterprise bean, the authentication service assigns it a certificate for the guest user. Any subsequent calls to enterprise beans are associated with the guest user.
  • If a web component is protected, you may specify three types of authentication: basic, form, and certificate. With basic authentication, the server instructs the Web browser to prompt for the user name and password. With form authentication, you can specify the .html form or .jsp file that prompts for the user name and security:passwordspassword. With certificate authentication, the server requests a certificate from the browser. In all types of authentication, if the web component calls as enterprise bean, the call is associated with the authenticated user.

## Authorization

Declaring Roles

  • When you design an enterprise bean, you should keep in mind what types of users will access the bean. For example, an Account enterprise bean might be accessed by customers, bank tellers, and branch managers. Each of these user categories is called a role.
  • A J2EE group also represents a category of users, but it has a different scope than a role.
  • A J2EE group is designated for the entire J2EE server, whereas a role covers only a specific application in a J2EE server.
  • To create a role for an application, you declare it for the EJB .jar or web component (.war) files contained in the application.

Declaring Method Permissions

  • After you've defined the roles, you're ready to define the method permissions of an enterprise bean.
  • Method permissions indicate which roles are allowed to invoke which methods.
  • You specify method permissions by mapping roles to methods with the Application Deployment Tool

Mapping Roles to J2EE Users and Groups

  • When you are developing an enterprise bean, you should know the roles of your users, but you probably won't know exactly who the users will be. That's okay, because after your bean has been deployed the administrator of the J2EE server will map the roles to the J2EE users (or groups) of the default realm.
  • Using the Application Deployment Tool, the administrator maps roles to J2EE users and groups
  • By default, the Role Name table assigns the ANYONE role to a method. The guest user, which is anonymous and unauthenticated, belongs to the ANYONE role. Therefore, if you do not map the roles, any user may invoke the methods of an enterprise bean.

Scenarios

The scenarios in this section show how authentication and authorization work together to manage security for J2EE applications.

J2EE Application Client

In this scenario, an employee named Bob has moved and he wishes to update his home address for his company's records. The company that Bob works for has a J2EE application that allows employees to update their personal information. Figure 8-1 illustrates this application. To change his address, Bob runs a J2EE application client that invokes the update method in the Employee enterprise bean.

Before Bob runs the client, the J2EE administrator sets up the security as follows:

         Only the Administrator and RegularEmployee roles may invoke the update method of the Employee enterprise bean.

         The J2EE group named FullEmployee belongs to the RegularEmployee role.

         The J2EE user Bob belongs to the FullEmployee group in the default realm.

The J2EE server performs the following security checks at run time:

1. When the J2EE application client starts running it opens a dialog that prompts for the J2EE user name and password, which Bob enters.

2. The authentication service verifies that Bob's user name and password exist in the default realm.

3. Bob clicks the update button in the client, which attempts to invoke the update method of the Employee enterprise bean.

4. The EJB container performs authorization. It verifies that the RegularEmployee role, to which Bob's group (FullEmployee) belongs, has permission to invoke the update method.

 

 

FIGURE 8-1 Authenticated Access to an Enteprise Bean

Web Browser Client

In the next scenario, illustrated in figure 8-2, Mary transfers money between her savings and checking accounts from her Web browser. To transfer the funds, Mary enters a URL that accesses a JSP component. This component calls a JavaBeansTM component, which invokes the transfer method of the Account enterprise bean.

The J2EE administrator enforces security with these rules:

         The JSP component is a protected resource.

         Only the Customer role may invoke the transfer method of the Account enterprise bean.

         The J2EE group named CurrentCustomer belongs to the Customer role.

         Mary's J2EE user belongs to the CurrentCustomer group in the default realm.

When Mary transfers the funds, the J2EE server enforces security as follows:

1. Mary's browser attempts to access the JSP component.

2. Because the component is a protected resource, authentication is required. The Web service requests the Web browser to prompt for the J2EE user name and password.

3. Mary enters her J2EE user name and password, which are passed back to the J2EE server.

4. The authentication service verifies that the user name and password exist in the default realm.

5. The Web browser is allowed to access the JSP component.

6. Mary clicks the Transfer button on the form generated by the JSP component, which calls a JavaBeans component.

7. The JavaBeans component attempts to invoke the transfer method of the Account enterprise bean.

8. Mary's J2EE group (CurrentCustomer) belongs to the Customer role, which is allowed to invoke the transfer method. Therefore, the EJB container authorizes the invocation.

 

FIGURE 8-2 Authenticated Access to a JSP Component and an Enterprise Bean

Bean-Managed Security

  • The security mechanisms described in the Authentication and Authorization sections are sufficient for most J2EE applications.
  • You control these mechanisms by declaring certain parameters with the Application Deployment Tool. Because this approach is declarative, you don't have to code your own security routines.
  • Some applications have special security requirements. For example, an application might make authorization decisions based on the time of day, the parameters of a call, or the internal state of an enterprise bean. Another application might restrict access based on user information stored in a database.
  • If your application has special security requirements, you may want to take advantage of the APIs described in the following sections.

Getting the Caller's J2EE User

         The getCallerPrincipal method of the EJBContext interface returns the java.security.Principal object that identifies the caller of the enterprise bean. (In this case, a principal is the same as a user.) In the following example, the getUser method of an enterprise bean returns the name of the J2EE user that invoked it:

 public String getUser() { return sessioncontext.getCallerPrincipal ().getName(); }

         To determine the caller of a servlet, you invoke the getUserPrincipal method.

Determining the Caller's Role

         You can determine whether an enterprise bean's caller belongs to a particular role by invoking the isCallerInRole method: boolean result = context.isCallerInRole("Customer");

         To determine the caller's role for a servlet, you invoke the isUserInRole method.

Security Policy Files

  • The J2EE server policy file is named server.policy. It resides in the $J2EE_HOME/lib/security directory.
  • The J2EE application client policy file, client.policy , resides in the same directory.

 


Database Connections


         The EJB container maintains the pool of database connections.

         This pool is transparent to the enterprise beans.

         When an enterprise bean requests a connection, the container fetches one from the pool and assigns it to the bean. Because the time-consuming connection has already been made, the bean quickly gets a connection. The bean may release the connection after each database call, since it can rapidly get another connection.

         And because such a bean holds the connection for a short time, the same connection may be shared sequentially by many beans.

         The persistence type of the enterprise bean determines whether or not you code the connection routine.

         You must code the connection for enterprise beans that access a database and do not have container-managed persistence. Such beans include entity beans with bean-managed persistence and session beans.

         For entity beans with container-managed persistence, the Application Deployment Tool generates the connect routines for you.

Coded Connections

  • The bean routine that connects to the database should not hardcode the actual name (URL) of the database. Instead, it should refer to the database with a logical name and use a JNDI lookup when obtaining the database connection. This level of indirection provides several benefits:
    • You can deploy the same enterprise bean in different environments that have databases with different names.
    • You can re-use the enterprise bean in multiple applications.
    • You can assemble the enterprise beans into applications that run in a distributed environment. (The enterprise beans and the databases they access may run on different machines.)
  • A resource manager is a storage mechanism such as a DBMS.
  • A resource manager connection is an object, such as java.sql.Connection, that represents a session with the resource manager (DBMS).
  • A resource manager connection factory is an object that creates resource manager connections. For example, a javax.sql.DataSource object is a connection factory because it creates a java.sql.Connection object.

How to Connect

The code examples in this section are from the the AccountEJB class, which was described in the the Entity Beans chapter. Because the AccountEJB class uses bean-managed persistence, it connects to the database with the following steps:

1. Specify the logical database name.

    private String dbName = "java:comp/env/jdbc/AccountDB";

         The java:comp/env/ prefix is the JNDI context for the component.

         The jdbc/AccountDB string is the logical database name.

2. Obtain the DataSource associated with the logical name.

         InitialContext ic = new InitialContext();
         DataSource ds = (DataSource) ic.lookup(dbName);

 

3. Get the Connection from the DataSource.

o        Connection con = ds.getConnection();

When To Connect

  • When coding an enterprise bean, you must decide how long the bean will retain the connection.
  • Generally you have two choices: either hold the connection for the lifetime of the bean, or only during each database call.
  • Your choice determines the method (or methods) in which your bean connects to a database.

Longterm Connections

  • You can design an enterprise bean that holds a database connection for its entire lifetime.
  • Because the bean connects and disconnects just once, its code is slightly easier to write.
  • But there's a tradeoff-- other enterprise beans may not acquire the connection. Session and entity beans issue the lifelong connections in different methods.

Session Beans

 

  • The EJB container invokes the ejbCreate method at the beginning of a session bean's life cycle, and invokes the ejbRemove method at the end. To retain a connection for the lifetime of a session bean, you connect to the database in ejbCreate and disconnect in ejbRemove.
  • If the session bean is stateful, you must also connect in ejbActivate and disconnect in ejbPassivate. A stateful session bean requires these additional calls because the EJB container may passivate the bean during its lifetime. During passivation, a stateful session bean is saved in secondary storage, but a database connection may not be saved in this manner.
  • Because a stateless session bean cannot be passivated, it does not require the additional calls in ejbActivate and ejbPassivate.

Entity Beans

  • After instantiating an entity bean and moving it to the pooled stage, the EJB container invokes the setEntityContext method. Conversely, the EJB container invokes the unsetEntityContext method when the entity bean leaves the pooled stage and becomes eligible for garbage collection.
  • To retain a database connection for its entire lifespan, an entity bean connects in the setEntityContext method and disconnects in the unsetEntityContext method.

Short-term Connections

  • Briefly held connections allow many enterprise beans to share the same connection.
  • Because the EJB container manages a pool of database connections, enterprise beans can quickly obtain and release the connections.
  • For example, a business method might connect to a database, insert a row, and then disconnect.
  • In a session bean, a business method that connects to a database should be transactional. The transaction will help maintain data integrity.

Container-Managed Connections

  • With container-managed persistence, the entity bean class does not contain the code that connects to a database. Instead, this code is generated by the Application Deployment Tool. Using the tool, you specify the JNDI name of the database in the JNDI Name field of the Deployment Settings dialog box.