Developing the Components of Entity EJBsWhether the entity bean type is CMP or BMP, the components are the same; only the implementation and contents of the deployment descriptor differ . The components of an entity EJB are
The local interfaces for entity EJBs were introduced with EJB 2.0. Previously, only session beans provided local interfaces. The local interface provides a high-performance communication path between the client and EJB when they reside within the same Java Virtual Machine. The local interface avoids the overhead associated with Remote Method Invocation (RMI), allowing the client to directly invoke methods of the EJB. This capability is particularly valuable for an entity bean that contains other entity beans as its attributes. The entity bean will communicate through the local interface, rather than the remote interface, resulting in much higher performance. For further information on RMI, see Chapter 12, "Distributed Processing Using RMI." Following the RMI protocol, the components of an EJB include a remote interface, home interface, and remote object. The EJB remote interface is the proxy used by the client to communicate with the EJB remote object. The EJB home interface is the factory to create an instance of an object that implements the remote interface. The EJB class, remote interface, and home interface are the components used to establish communication between the EJB client and the entity EJB. The remaining components for an entity EJB are the primary key classes and deployment descriptors. Unlike a session EJB, a primary key class is a required component for an entity EJB. An entity EJB establishes and maintains a mapping to persistent storage in a database. When the entity bean is created, through the create() method of the home interface, a corresponding database insert operation is performed. When the entity bean is removed, through the remove() method of the home interface, a database delete operation is performed. A simple entity bean will map to a single row in a database table. The attributes of the entity bean correspond to the columns in the table. More complex implementations can be mapped by the bean provider, using Bean-Managed Persistence, or by the container using Container-Managed Persistence with Container-Managed Relationships. In order to develop the components for an EJB, the Java2 Enterprise Edition is required. Specifically, j2ee.jar contains the classes in the javax.ejb package. Your EJB components establish inheritance and composition relationships with the classes in the java.rmi and javax.ejb classes. It is valuable to gain an understanding of the J2EE interfaces that are being used by the EJB. Table 21.2 provides a brief description of the API for selected interfaces that are used by entity bean providers from the javax.ejb package. Note WebLogic Server 7.0 provides the J2EE classes in \bea\weblogic700\server\lib\weblogic.jar. This jar file replaces j2ee.jar when developing on WebLogic Server. Table 21.2. The API for Selected Interfaces from the javax.ejb Package
EJB Remote InterfaceThe remote interface defines the public API for the entity bean. The bean provider writes the remote interface, and the WebLogic EJB container implements the interface when the bean is deployed. The purpose of an entity EJB is to provide persistent storage for the enterprise application. The methods in the remote interface are therefore getter and setter methods for the attributes in the data model of this entity bean. The remote interface must be public and must extend the javax.ejb.EJBObject interface. Following the requirements of RMI, each method in the remote interface must declare that it throws RemoteException . As with any JavaBean interface, the designer chooses which attributes are read/write and which are read-only. The read/write attributes will have get and set methods; the read-only attributes will have only a get method. The bookstore example was first presented in Chapter 13, "Accessing Data Repositories Using JDBC." In the new example, shown in Listing 21.5, a book is created with a title, author, and price. After the book is created, the title and author cannot be changed. These will be read-only attributes. The only attribute that can be changed is the price. This API determines that title and author will have only get methods; the price will have get and set methods. Listing 21.5 Remote Interface for the BookEntity EJB/** * Remote interface for the BookEntity EJB */ package com.objectmind.BookStore; import java.rmi.RemoteException; import javax.ejb.EJBObject; public interface BookEntity extends EJBObject { public String getTitle() throws RemoteException; public String getAuthor() throws RemoteException; public float getPrice() throws RemoteException; public void setPrice( float price ) throws RemoteException; } EJB Local InterfaceThere are only two differences between the remote interface and the local interface. The local interface
Listing 21.6 shows the implementation of the local interface for the Book entity bean. Other than these two differences, the BookEntity and BookEntityLocal interfaces declare the same methods. Listing 21.6 Local Interface for the BookEntity EJB/** * Local interface for the BookEntity EJB */ package com.objectmind.BookStore; import javax.ejb.EJBLocalObject; public interface BookEntityLocal extends EJBLocalObject { public String getTitle(); public String getAuthor(); public float getPrice(); public void setPrice( float price ); } Using the EJB Value ObjectIn a multitier architecture, each invocation of an EJB method (Session or Entity bean) from the presentation tier , is a network overhead. As the number of remote method invocations increases, the probability for the application to incur a degrade in performance also increases . In such a scenario, a more performance-oriented approach to configure an entity bean is to create a value object class. The value object is written as a standard JavaBean with private attributes and public getters and setters. A common naming convention is to add the letters VO to the end of the name of the entity bean class. BookEntityVO would therefore be the value object for the BookEntity EJB. The attributes of the value object are the same as the attributes of the entity bean. Rather than passing individual parameters to the create() method of the home interface, you pass the single value object, which reduces the number of remote method calls. Following this implementation, the ejbCreate() and ejbPostCreate() methods of the entity bean would also have the value object as their single parameter. Tip Rather than passing many parameters to create() , ejbCreate() , and ejbPostCreate() , implement a simple JavaBean to act as a value object. The value object for the BookEntity EJB contains the title, author, price, and ID for the book (see Listing 21.7). Listing 21.7 Sample Value Object for the BookEntity EJB/** * Value object for the BookEntity EJB */ package com.objectmind.BookStore; import java.io.Serializable; public class BookEntityVO implements Serializable { private String bookID; private String title; private String author; private float price; public String getBookID() { return bookID; } public void setBookID(String value) { bookID = value; } public String getTitle() { return title; } public void setTitle(String value) { title = value; } public String getAuthor() { return author; } public void setAuthor(String value) { author = value; } public float getPrice() { return price; } public void setPrice(float value) { price = value; } } EJB Remote Home InterfaceThe EJB remote home interface is a factory that is responsible for providing an instance of an object that implements the remote interface. The reference is either created as a new instance using the create() method, or an existing instance can be located using finder methods. Only remote home interfaces provide finder methods to locate and use existing beans. This allows multiple clients to share the same entity bean. As with the remote interface, the bean provider writes the home interface, and the WebLogic EJB container implements the home interface when the bean is deployed. A common naming convention for the home interface is to simply append Home to the name of the remote interface. The home interface for the BookEntity is therefore BookEntityHome . The home interface must be a public interface that extends javax.ejb.EJBHome . The create() method in the home interface is effectively a constructor. The parameters to create() are application dependent and used to initialize the EJB. The return type for create() is the remote interface, which extends EJBObject. The calling client then invokes methods on the bean via the remote interface. Refer to Figure 21.1 for a diagram showing the EJBObject and the EJB entity bean. The create() method is declared with a throws clause for javax.ejb.CreateException and java.rmi.RemoteException . The home interface also provides finder methods to locate instances of existing entity EJBs. There must be a method named findByPrimaryKey() whose parameter is the same type as the primary key. Additional finder methods are implemented to provide application-specific features for the API of the entity EJB. For example, BookEntityHome provides a finder method to return a collection of all books by a given author. The return type for the finder methods is the remote interface for a single instance match, or a java.util.Collection to return a list of matching instances. Note The create() method in the home interface may be overloaded for different parameter lists. The EJB class must have ejbCreate() methods along with their corresponding ejbPostCreate() methods overloaded with the same parameter lists as the create() methods. Listing 21.8 includes examples for both return types from finder methods. The findByPrimaryKey() method returns the Book remote interface of the object that has the unique primary key. The findBooksByAuthor() method returns a java.util.Collection of remote objects matching the requested author. Note For BMP, the bean provider must implement the finder methods declared in the home interface through the coding of its corresponding ejbFind ... methods. Although, in CMP, the ejbFind ... methods cannot be declared in the bean, the methods must be declared in the bean's home interface. The container will provide the implementation. Listing 21.8 Sample Remote Home Interface for the BookEntity EJB/** * BookEntityHome is the home interface for the BookEntity EJBObject. */ package com.objectmind.BookStore; import java.rmi.RemoteException; import java.util.Collection; import javax.ejb.EJBHome; import javax.ejb.CreateException; import javax.ejb.FinderException; public interface BookEntityHome extends EJBHome { /** * Create method for BookEntity * @param value value object BookEntityVO * @return BookEntity EJBObject */ public BookEntity create(BookEntityVO value) throws CreateException, RemoteException; /** * Finder method by primary key * @param key book title is the primary key * @return Book object matching primary key */ public BookEntity findByPrimaryKey( BookEntityPK key ) throws FinderException, RemoteException; /** * Finder method to create a list of books by author * @param author book author to match * @return collection of BookEntity objects in a Vector */ public Collection findBooksByAuthor( String author ) throws FinderException, RemoteException; /** * Finder method to find a book by title * @param title book title to match * @return collection of BookEntity objects in a Vector */ public BookEntity findBookByTitle( String title ) throws FinderException, RemoteException; } EJB Local Home InterfaceThere are only three differences between the remote home interface and the local home interface. The local home interface
Listing 21.9 shows the implementation of the local home interface for the Book entity bean. Other than these three differences, the BookEntityHome and BookEntityLocalHome interfaces declare the same methods. Listing 21.9 Local Home Interface for the BookEntity EJB/** * BookEntityLocalHome is the home interface for the BookEntity EJBObject. */ package com.objectmind.BookStore; import java.util.Collection; import javax.ejb.EJBLocalHome; import javax.ejb.CreateException; import javax.ejb.FinderException; public interface BookEntityLocalHome extends EJBLocalHome { /** * Create method for BookEntity * @param value value object BookEntityVO * @return BookEntity EJBObject */ public BookEntityLocal create(BookEntityVO value) throws CreateException; /** * Finder method by primary key * @param key book title is the primary key * @return BookEntity object matching primary key */ public BookEntityLocal findByPrimaryKey( BookEntityPK key ) throws FinderException; /** * Finder method to create a list of books by author * @param author book author to match * @return collection of BookLocal objects */ public Collection findBooksByAuthor( String author ) throws FinderException; /** * Finder method to find a book by title * @param title book title to match * @return collection of BookEntity objects in a Vector */ public BookEntityLocal findBookByTitle( String title ) throws FinderException; } |