Enterprise Beans


Enterprise Beans are the server-side components used in the component architecture of Enterprise JavaBeans. They implement the application logic on which the client programs rely. The functionality of the server and the EJB container ensures only that beans can be used. Enterprise Beans are installed in an EJB container, which offers them an environment at run time in which they can exist. Enterprise Beans rely implicitly or explicitly on the services that the EJB container offers:

Implicitly in the case of

  • container-managed persistence (CMP);

  • declarative transactions;

  • security.

Explicitly in the case of

  • The use of explicit transactions;

  • bean-managed persistence (BMP);

  • the sending of asynchronous messages.

Types of Enterprise Beans

There are three different forms of Enterprise Beans, which differ more or less sharply one from the other: entity beans, message-driven beans, and session beans. Table 3-1 describes the basic differences among these three types of Enterprise Beans.

Table 3-1: Defining characteristics distinguishing session, message-driven, and entity Beans (see [25]).

Session Bean

Message-Driven Bean

Entity Bean

Task of the bean

Represents a server-side service that executes tasks for a client.

Represents server-side enterprise logic for the processing of asynchronous messages.

Represents an enterprise object whose data are located in permanent storage.

Access to the bean

A session bean is a private resource for the client, available to the client exclusively.

A message-driven bean is not directly accessible to the client. Communication is effected exclusively via sending messages over a particular channel of the message service.

An entity bean is a central resource; the bean instance is used simultaneously by several clients, and its data are available to all clients.

Persistence of the bean

Not persistent. When the bound client or server is terminated, the bean is no longer accessible.

Not persistent. When the server is terminated, the bean is no longer accessible. The messages that have not yet been delivered to the bean are persistent as required. (More on this in Chapter 6.)

Persistent. When bound clients or server is terminated, the state of the entity bean is located in a persistent storage medium. The bean can be recreated at a later time.

Session beans model ordinary processes or events. For example, this could be the entering of a new customer in an enterprise resource planning system (ERP), the execution of a booking in a booking system, or setting a production plan based on open orders. Session beans can be viewed as an extension of the client's arm toward the server. This point of view is supported by the fact that a session bean is a private resource of a particular client.

Entity beans, on the other hand, represent objects in the real world that are associated with particular data, such as a customer, a booking account, or a product. An instance of a particular entity bean type can be used simultaneously by several clients. Session beans usually operate on data represented by entity beans.

Message-driven beans are recipients of asynchronous messages. A message service acts as a mediator between the sender of a message and the message-driven bean. Entity and session beans are addressed via the remote or local interface. Calls to entity or session beans are synchronous; that is, the execution of the client is blocked until the method of the Enterprise Bean has been processed. After the method call has returned, the client can continue its processing. Message-driven beans can be addressed by the client only (indirectly) by sending a message over a particular channel of the message service. A particular type of message-driven bean receives all messages that are sent over a particular channel of the message service. Communication over a message service is asynchronous. That is, the execution of the client can proceed directly after a message is sent. It does not remain blocked until the message has been delivered and processed. The container can deploy several instances of a particular message-driven bean type for the processing of messages. Thus in this case parallel processing is possible. Message-driven beans have no state between the processing of several messages. Furthermore, they have no identity vis- -vis the client. In a certain sense the are similar to stateless session beans (see the following paragraph). For the processing of a message, message-driven beans can use session or entity beans as well as all services that the container offers.

There is another distinction to be made with regard to session beans, namely, whether a session bean is stateless or stateful. Stateless session beans do not store any data from one method call to the next. The methods of a stateless session bean operate only with the data that are passed to it as parameters. Stateless session beans of the same type all possess the same identity. Since they have no state, there is neither the necessity nor the possibility of distinguishing one from the other.

Stateful session beans, on the other hand, store data over many method calls. Calls by methods to stateful session beans can change the state of the bean. The state is lost when the client is no longer using the bean or when the server is taken down. Stateful session beans of the same type have differing identities at run time. The EJB container must be able to distinguish them, since they have differing states for their clients.

A session bean receives its identity from the EJB container. In contrast to entity beans, the identity of a session bean is not externally visible. Since clients always work with a session bean that for them is an exclusive instance, there is no need for such visibility.

Entity beans can be distinguished by whether they themselves are responsible for making their data persistent or whether the EJB container takes over this task. In the first case one speaks of bean-managed persistence, while in the second the talk is of container-managed persistence.

Entity beans of the same type have differing identities at run time. An entity bean of a particular type is identified at run time by its primary key, which is allocated by the EJB container. It is thereby bound to particular data, which it represents in its activation phase. The identity of an entity bean is outwardly visible.

The bean types play a role in resource management of the EJB container. With entity beans, message-driven beans, and stateless session beans the container can instigate pooling, while with stateful session beans it can instigate passivation and activation (serialization and deserialization onto a secondary storage medium).

The interface between an entity bean and the EJB container is called the context (javax.ejb.EJBContext). This interface is again specialized for the three bean types (to javax.ejb.EntityContext, javax.ejb.MessageDrivenContext, and javax.ejb.SessionContext). The bean can communicate with the container using the context that is passed by the EJB container to the bean. The context remains bound to a bean during its entire life span. By means of the context the EJB container manages the identity of an Enterprise Bean. With a change in the context the EJB container can change the identity of a bean.

Chapters 4, 5, and 6 provide an extensive discussion of the technical details of session, message-driven, and entity beans. The second section of Chapter 9 deals with the differing semantics of the various bean types.

Components of an Enterprise Bean

An Enterprise Bean possesses the following components:

  • The remote interface and the (remote) home interface or the local and local home interface (for entity and session beans);

  • The bean class (for entity, message-driven, and session beans);

  • The primary key or primary key class (for entity beans);

  • The deployment descriptor (for entity, message-driven, and session beans).

One speaks of the remote client view when an Enterprise Bean is addressable over the remote interface. If an Enterprise Bean uses the local interface, one speaks of the local client view. Basically, an Enterprise Bean can support both the local and remote client views. However, the specification advises that one choose one of the two cases.

Let us describe the individual components of a bean by way of an example. We would like to develop an entity bean that represents a bank account. The components should make it possible to ascertain the account number, a description of the account, and the current balance of the account. Furthermore, the balance of the account should be capable of being raised or lowered by an arbitrary amount. The bank-account bean should be able to be addressed by the remote client, that is, from a client that is located outside the address space of the bank-account bean.

This chapter concentrates on the representation of the special features determined by the architecture. In this example we shall not go into the special features of a particular bean type (that will be done extensively in Chapters 4, 5, and 6). Since an entity bean exhibits all the components mentioned above, it is best suited for this introductory example. Moreover, we shall not use the local interface in this example. Since EJB is a distributed component architecture, the use of the remote interface is standard. The use of the local interface is analogous to that of the remote interface, and it will be dealt with in Chapters 4 and 5.

Remote Interface

The remote interface defines those methods that are not offered externally by a bean. The methods of the remote interface thus reflect the functionality that is expected or demanded by the components. The remote interface must be derived from javax.ejb.EJBObject, which in turn is derived from java.rmi.Remote. All methods of the remote interface must declare the exception java.rmi.RemoteException. See Listing 3-1.

Listing 3-1: Remote interface of BankAccount.

start example
 package ejb.bankaccount; import java.rmi.RemoteException; import javax.ejb.EJBObject; public interface BankAccount extends EJBObject {   //ascertain account number   public String getAccNumber()     throws RemoteException;   //ascertain account description   public String getAccDescription()     throws RemoteException;   //ascertain account balance   public float getBalance()     throws RemoteException;   //increase account balance   public void increaseBalance(float amount)     throws RemoteException;   //reduce account balance   public void decreaseBalance(float amount)     throws RemoteException; } 
end example

Home Interface

The home interface must be derived from javax.ejb.EJBHome (in this interface is to be found the method for deleting a bean; it does not need to be separately declared). EJBHome, for its part, is likewise derived from javax.rmi.Remote.In the home interface as well all methods declare the triggering of an exception of type java.rmi.RemoteExeption. As in the case of the remote interface, everything points to the distributed character and the embedding in the EJB framework. See Listing 3-2.

Listing 3-2: The home interface of BankAccount.

start example
 package ejb.bankaccount; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; import javax.ejb.FinderException; public interface BankAccountHome extends EJBHome {   //generate an account   public BankAccount create(String accNo,                                   String accDescription,                                   float initialBalance)     throws CreateException, RemoteException;   //find a particular account   public BankAccount findByPrimaryKey(String accPK)     throws FinderException, RemoteException; } 
end example

Bean Classes

Bean classes implement the methods that have been declared in the home and remote interfaces (with the exception of the findByPrimaryKey method), without actually implementing these two interfaces. The signatures of the methods of the remote and home interfaces must agree with the corresponding methods in the bean class. The bean class must implement an interface that depends on its type, and indeed, it must be javax.ejb.EntityBean, javax.ejb.MessageDrivenBean,or javax.ejb.SessionBean. The bean implements neither its home nor its remote interface. Only in the case of an entity bean with container-managed automatic persistence is the class abstract. The classes of session, message-driven, and entity beans, which manage their own persistence, are concrete classes. See Listing 3-3.

Listing 3-3: Bean class of BankAccount.

start example
 package ejb.bankaccount; import javax.ejb.CreateException; import javax.ejb.EntityBean; import javax.ejb.EntityContext; import javax.ejb.RemoveException; public abstract class BankAccountBean implements EntityBean {   private EntityContext theContext;   public BankAccountBean() {   }   //the create method of the home interface   public String ejbCreate(String accNo,                                    String accDescription,                                    float initialBalance)     throws CreateException   {     setAccountNumber(accNo);     setAccountDescription(accDescription);     setAccountBalance(initialBalance);     return null;   }   public void ejbPostCreate(String accNo,                                    String accDescription,                                    float initialBalance)     throws CreateException   {   }   //abstract getter/setter methods   public abstract String getAccountNumber();   public abstract void setAccountNumber(String acn);   public abstract String getAccountDescription();   public abstract void setAccountDescription(String acd);   public abstract float getAccountBalance();   public abstract void setAccountBalance(float acb);   //the methods of the remote interface   public String getAccNumber() {     return getAccountNumber();   }   public String getAccDescription() {     return getAccountDescription();   }   public float getBalance() {     return getAccountBalance();   }   public void increaseBalance(float amount) {     float acb = getAccountBalance();     acb += amount;     setAccountBalance(acb);   }   public void decreaseBalance(float amount) {     float acb = getAccountBalance();     acb -= amount;     setAccountBalance(acb);   }   //the methods of the javax.ejb.EntityBean interface   public void setEntityContext(EntityContext ctx) {     theContext = ctx;   }   public void unsetEntityContext() {     theContext = null;   }   public void ejbRemove()     throws RemoveException   {   }   public void ejbActivate() {   }   public void ejbPassivate() {   }   public void ejbLoad() {   }   public void ejbStore() {   } } 
end example

Primary Key (Primary Key Class)

The primary key is relevant only for entity beans. Its purpose is to identify an entity of a particular type uniquely. As in the case of the primary key of a database table, it contains those attributes that are necessary for unique identification. With the primary key a particular entity can be found, which then is associated by the EJB container with an entity bean instance of the correct type. With the primary key the identity of an entity bean is externally visible. The primary key class is irrelevant for session and message-driven beans, since their identity is never externally visible. The specification distinguishes two types of primary keys:

  • primary keys that refer to a field of the entity bean class;

  • primary keys that refer to several fields of the entity bean class.

A primary key that refers to only a single field of the entity bean class can be represented by a standard Java class (for example, java.lang.String, java.lang.Integer). In our example the class java.lang.String is the primary key class, since the unique identification of an account is possible via its (alphanumeric) account number.

A primary key that refers to several fields of the entity bean class is represented, as a rule, by a class specially developed for that purpose. Such a class must be a public class, and it must have a public constructor without arguments. The fields of the primary key class that represent the primary key of the entity bean must address those of the entity bean class by name. Furthermore, these fields must also be public. The class must be RMI-IIOP compatible (serializable), and it must implement the methods equals() and hashCode(). Listing 3-4 shows an example of such a primary key class for an account bean that requires for its unique identification the number of the client as well as the account number (client-capable system).

Listing 3-4: Example of a primary key class for multipart keys.

start example
 package ejb.custom; public class CustomAccountPK implements java.io.Serializable {   public String clientNumber;   public String accountNumber;   public CustomAccountPK() {   }   public int hashCode() {     return clientNumber.hashCode() ^        accountNumber.hashCode();   }   public boolean equals(Object obj) {     if(!(obj instanceof CustomAccountPK)) {       return false;     }     CustomAccountPK pk = (CustomAccountPK)obj;     return (clientNumber.equals(pk.clientNumber)       && accountNumber.equals(pk.accountNumber));   }   public String toString() {     return clientNumber + ":" + accountNumber;   } } 
end example

The Deployment Descriptor

The deployment descriptor is a file in XML format (details on XML can be found in [3]) that describes one or more beans or how several beans can be collected into an aggregate. All such information that is not to be found in the code of a bean is placed in the deployment descriptor. Essentially, this is declarative information. This information is of particular importance for those collecting several Enterprise Beans into an application or installing Enterprise Beans in one EJB container. The EJB container is informed via the deployment descriptor how it is to handle the component(s) at run time.

The deployment descriptor contains information on the structure of an Enterprise Bean and its external dependencies (for example, to other beans or to particular resources such as connections to a database). Furthermore, it contains information about how the components should behave at run time or how they can be combined with other components into more complex building blocks. We shall illustrate this for our example bean by showing in Listing 3-5 a suitable complete deployment descriptor (for a full description of the deployment descriptor see [21]).

Listing 3-5: Deployment descriptor of BankAccount.

start example
 <?xml version="1.0" ?> <ejb-jar version="2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd">   <description>     This deployment descriptor contains information on     the entity bean BankAccount.   </description>   <enterprise-beans>     <entity>       <!-- Name of the Enterprise Bean -->       <ejb-name>BankAccount</ejb-name>       <!-- class of the Home Interface -->       <home>ejb.bankaccount.BankAccountHome</home>       <!-- class of the Remote Interface -->       <remote>ejb.bankaccount.BankAccount</remote>       <!-- class of the Enterprise Bean -->       <ejb-class>ejb.bankaccount.BankAccountBean</ejb-class>       <!-- type of persistence -->       <persistence-type>Container</persistence-type>       <!-- class of the primary key -->       <prim-key-class>java.lang.String</prim-key-class>       <!-- specifies whether the implementation of the        Enterprise Bean is reentrant -->       <reentrant>False</reentrant>       <!-- the EJB version for which this Enterprise        Bean was developed -->       <cmp-version>2.x</cmp-version>       <!-- Name of the persistence mechanism -->       <abstract-schema-name>AccountBean       </abstract-schema-name>       <!-- list of the persistent attributes        of the Enterprise Bean -->       <cmp-field>         <description>account number</description>         <field-name>accountNumber</field-name>       </cmp-field>       <cmp-field>         <description>account description</description>         <field-name>accountDescription</field-name>       </cmp-field>       <cmp-field>         <description>account balance</description>         <field-name>accountBalance</field-name>       </cmp-field>       <!-- primary key field -->       <primkey-field>accountNumber</primkey-field>     </entity>   </enterprise-beans>   <assembly-descriptor>     <!-- Definition of the user role 'Banker'-->     <security-role>       <description> the role of the banker       </description>       <role-name>Banker</role-name>     </security-role>     <!-- Definition of access rights at the method level-->     <method-permission>       <role-name>banker</role-name>       <method>         <ejb-name>BankAccount</ejb-name>         <method-name>*</method-name>       </method>     </method-permission>     <!-- Definition of transactional behavior       per method of the Enterprise Bean -->     <container-transaction>       <method>         <ejb-name>BankAccount</ejb-name>         <method-name>increaseBalance</method-name>       </method>       <trans-attribute>Required</trans-attribute>     </container-transaction>     <container-transaction>       <method>         <ejb-name>BankAccount</ejb-name>         <method-name>decreaseBalance</method-name>       </method>       <trans-attribute>Required</trans-attribute>     </container-transaction>   </assembly-descriptor> </ejb-jar> 
end example

Since our example deals with an entity bean with container-managed persistence, instructions for the persistence manager must also be provided. It must know which fields of the bean are to be mapped to which columns in which table or tables. Moreover, it requires instructions about the database in which the data are to be stored. The specification does not specify what form these instructions are to take. It prescribes only that the creator must provide tools by means of which such instructions can be supplied. It is thus clear that these tools will be different depending on the creator, as also will be the format in which the instructions are provided. In the simplest case these instructions can be given in a file in XML format. Listing 3-6 shows an imaginary example. Later in this chapter we shall call these instructions the persistence descriptor.

Listing 3-6: Example of mapping instructions for the persistence manager.

start example
 <abstract-schema>  <name>AccountBean</name>  <data-source>   <name>test-db</name>   <type>oracle</type>  </data-source>  <table-name>account</table-name>  <field-mapping>   <bean-field>accountNumber</bean-field>   <column>acno</column>  </field-mapping>  <field-mapping>   <bean-field>accountDescription</bean-field>   <column>acdesc</column>  </field-mapping>  <field-mapping>   <bean-field>accountBalance</bean-field>   <column>acbal</column>  </field-mapping> </abstract-schema> 
end example

If all components are present, then according to bean type, the home and remote interfaces, the bean class(es), the primary key class(es), and the deployment descriptor (which can contain a description of several Enterprise Bean components) are packed in JAR format into a file. The acronym JAR stands for "Java archive" and corresponds to the popular ZIP format. The components of an Enterprise Bean are then complete and are packed as component(s) in a jar file (further details on packing a component in a jar file can be found in [21]). Table 3-2 shows once more which components are relevant to which bean type.

Table 3-2: Overview of the components of various bean types.

Entity

Session

Message-Driven

Container Managed

Bean Managed

Remote, local interface

X

X

X

Local & remote home interface

X

X

X

Concrete bean class

X

X

X

Abstract bean class

X

Deployment descriptor

X

X

X

X

Persistence descriptor

X




Enterprise JavaBeans 2.1
Enterprise JavaBeans 2.1
ISBN: 1590590880
EAN: 2147483647
Year: 2006
Pages: 103

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net