7.1 Client View of an Entity Bean

We begin by describing the client view of an entity bean: the view seen by an application developer who uses an entity bean in a client application. Note that the client application developer is typically different from the developer or company that developed the bean.

An entity bean is a component that gives its client a true object-oriented abstraction of a business entity or a business process. For example, a real-life business entity may be an account, employee, customer, and so forth. A business process, on the other hand, can be the sequence involved in granting a loan approval, opening a bank account, scheduling a meeting, and so forth. When an entity bean is used to implement a business entity or a process, each individual business entity or process is represented by an entity object.

In most cases, entity beans are used with a local client view. Such entity beans are developed with local interfaces, which enable the bean to take advantage of the complete range of the EJB 2.0 and 2.1 architectural features. For example, an entity bean implemented with container-managed persistence can participate in container-managed relationships with other entity beans. With container-managed relationships, the EJB container manages the persistent relationships between entity beans much like it manages a bean's persistence.

Entity beans with local interfaces make the most use of the resources of the EJB environment. However, the beans are restricted to being colocated on the same JVM as their clients. When an entity bean's application is such that the bean must provide a remote client view, the developer can take steps to use the local-view advantages and still retain distributed capabilities. Principally, the developer can provide a session bean with a remote client view as a facade to entity beans with local views. Or, the developer can provide the entity bean itself with a remote interface in addition to its local interface.

Four concepts define the client view of an entity bean:

  1. Home interface

  2. Component interface: local and remote interfaces

  3. Primary key and object identity

  4. Life cycle of an entity object

In the following sections, we explain and illustrate how a client uses the home and component interfaces to manipulate entity objects. We also discuss the role of the primary key in the client view and explain the life cycle of an entity bean.

7.1.1 Home Interface

A client uses the home interface to manage the life cycle of individual entity objects. Life-cycle operations involve creating, finding, and removing entity objects. Specifically, the client uses the home interface methods to create new entity objects and to find and remove existing ones.

A client can also use business methods on the home interface to perform aggregate operations on entity objects. Keep in mind that these aggregate operations are not specific to any particular entity object.

In addition, a client can use the home interface to obtain the javax.ejb.EJBMetaData interface for the entity bean and to obtain a handle for the home interface. These functions apply only to entity beans implementing a remote home interface.

Although the signatures of the create and find methods may be different for each entity bean, the life-cycle operations are uniform across all entity beans. This uniformity makes it easier for a client developer to use entity beans supplied by other developers.

Let's look at the example AccountHome interface, which was used in Chapter 2. Code Example 7.1 shows the AccountHome interface with a local client view:

Code Example 7.1 AccountHome Interface
 import javax.ejb.CreateException; import javax.ejb.FinderException; public interface AccountHome extends javax.ejb.EJBLocalHome {    // create methods    Account create(String lastName, String firstName)       throws CreateException, BadNameException;    Account createBusinessAcct(String businessName)       throws CreateException;    ...    // find methods    Account findByPrimaryKey(AccountKey primaryKey)       throws FinderException;    Collection findInactive(Date sinceWhen)       throws FinderException, BadDateException;    ...    // home methods    public void debitAcctFee(float fee_amt)        throws OutofRangeException;    ... } 

Recall that the AccountHome interface previously implemented a remote client view and thus extended the javax.ejb.EJBHome interface. A home interface for an entity bean that implements a local client view extends the javax.ejb.EJBLocalHome interface. See Section 2.3.2, Enterprise Bean Home Interfaces, on page 33. The next sections explain the client's use of the home interface.

Locating the Home Interface

The client must first obtain the home interface to use it. A client obtains the local home interface for the AccountEJB entity bean from the client's environment, using the JNDI API, casting the returned value to the home interface type. The deployer has configured the home interface in the JNDI namespace (Code Example 7.2):

Code Example 7.2 Obtaining a Local Home Interface
 Context initCtx = new InitialContext(); AccountHome accountHome = (AccountHome) initCtx.lookup(    "java:comp/env/ejb/CheckingAccountEJB"); 

If the AccountEJB entity bean uses a remote client view, a client also obtains the remote home interface for the bean from the client's environment, using JNDI. However, the client must use the PortableRemoteObject.narrow method to cast the value returned from JNDI to the home interface type (Code Example 7.3):

Code Example 7.3 Obtaining a Home Interface for a Bean with a Remote View
 Context initCtx = new InitialContext(); AccountHome accountHome = (AccountHome)PortableRemoteObject.narrow(       initCtx.lookup("java:comp/env/ejb/CheckingAccountEJB"),       AccountHome.class); 
Using Create Methods

An entity bean home interface defines zero or more create methods, each representing a different way to create a new entity object. Each create method must begin with the word create and may be followed by a descriptive word. The number and types of the input parameters of the create methods are entity bean specific. The return value type for all create methods is always the entity bean's component interface.

Returning to our example, the client can use the AccountHome interface to create new Account objects, as follows:

 Account account1 = accountHome.create("Matena", "Vlada"); Account account2 = accountHome.create("Stearns", "Beth"); Account businessAcct = accountHome.createBusinessAcct(        "ComputerEase Publishing"); 

It is important to understand that when the client invokes a create operation, the entity bean creates the representation of the entity object's state in a persistent store, such as a relational database. This is in contrast to invoking a create method on a session bean. Invoking a create method on a session bean results only in the creation of a session bean instance; it does not result in the creation of persistent state in a persistent store.

It is possible for a home interface to define no create methods, and sometimes this approach is useful and preferable. Because the entity object's state exists in the resource manager independently from the entity bean and its container, it is possible to create or remove an entity object directly in the resource manager. (The section Entity Object State and Persistence on page 176 explains how a resource manager manages the state of an entity object.)

An application is not limited to going through the entity bean and its container to create or remove the object. For example, an application can use SQL statements to create or remove an Account object in a relational database. In some situations, the bean developer does not want to allow the entity bean clients to create entity objects and instead wants to ensure that the entity objects are created solely by other means. In such a case, the entity bean's home interface would have zero create methods. This is discussed in more detail in Section 7.2.7, Using Entity Beans with Preexisting Data, on page 235.

Using Find Methods

The home interface defines one or more find methods. A client uses the find methods to look up entity objects that meet given criteria.

All entity bean home interfaces define a findByPrimaryKey method to allow the client to find an entity object by its primary key. The findByPrimaryKey method takes a single input parameter with a type that is the entity bean's primary-key type. The return value type is the entity bean's component interface.

Our example AccountEJB client may use the findByPrimaryKey method, as follows:

 AccountKey pk = new AccountKey(); pk.setAccountNumber("100-300-423"); try {     Account account = accountHome.findByPrimaryKey(pk); } catch (ObjectNotFoundException ex) {     // account with the given primary key does not exist } 

If the findByPrimaryKey method completes successfully, the client knows that the entity object with the given primary key exists. If the entity object does not exist when the client invokes the findByPrimaryKey method, the method throws javax.ejb.ObjectNotFoundException to the client.

In addition to the required findByPrimaryKey method, the home interface may include additional find methods. The number and types of the input arguments of these additional find methods are entity bean specific. A find method's return value type is either the entity bean's component interface or java.util.Collection. Any find methods that can potentially find more than one entity object should define the return value type as java.util.Collection; those that can return at most one entity object should define the return value type as the component interface type.

The following example illustrates using a find method, findInactive, that may return more than one entity object:

 Date sinceDate = ...; Collection inactiveAccounts = accountHome.findInactive(sinceDate); Iterator it = inactiveAccounts.iterator(); while (it.hasNext()) {    Account acct = (Account) it.next(),    // do something with acct    acct.debit(100.00); } 

The findInactive method returns a collection of accounts that have been inactive since a given date. The client uses an iterator to obtain the individual entity objects returned in Collection.

Note that, had the bean used a remote client view, the client must use the PortableRemoteObject.narrow operation to cast an object retrieved from the collection to the entity bean's remote interface type. The client cannot simply retrieve the next object in Collection:

 Account acct = (Account) it.next(); 

Instead, the client performs the retrieval as follows:

 Account acct = (Account)PortableRemoteObject.narrow(it.next(),                   Account.class); 
Using remove Methods

As noted earlier, all entity bean local home interfaces extend the javax.ejb.EJBLocalHome interface, and all entity bean remote home interfaces extend the javax.ejb.EJBHome interface. The EJBLocalHome interface defines one remove method, whereas the EJBHome interface defines two remove methods. A client uses the EJBHome or EJBLocalHome remove methods to remove the entity objects specified by the method's input parameter.

The void remove(Object primaryKey) method is defined by the EJBHome and EJBLocalHome interfaces. This method is used to remove an entity object by a given primary key. The void remove(Handle handle) method, defined by the EJBHome interface only for remote home interfaces, is used to remove an entity object identified by a given handle. The following code illustrates using a remove method:

 AccountKey pk = new AccountKey(); pk.setAccountNumber("100-300-423"); accountHome.remove(pk); 

It is important to understand that successful execution of a remove method results in the removal of the representation of the entity object's state from the resource manager that stores the state. In the previous example, the remove method results in the removal of the specified account record from the database.

Using Home Business Methods

The home interface may also define business methods that operate across all bean instances. Suppose that a client wants to periodically subtract a set fee from all account records. Rather than having to write code to retrieve all Account instances and subtract a set amount from each account's balance, a client might use AccountHome's debitAcctFee method to accomplish this same operation across all Account instances. For example:

 if (monthlyUpdate) {      accountHome.debitAcctFee(acctFee); } 

7.1.2 Component Interface

To get a reference to an existing entity object's component interface either its remote interface or its local interface the client can

  • Receive the reference as a result of a create method

  • Find the entity object by using a find method defined in the entity bean's home interface

  • Receive the reference as an input parameter or a method result in a method call

Once it obtains the reference to the entity bean's component interface, the client can do a number of things with that reference:

  • Invoke business methods on the entity object through the component interface

  • Obtain a reference to the entity bean's home interface

  • Pass the reference in a parameter or as a result of a remote or local method call

  • Obtain the entity object's primary key

  • Remove the entity object

Code Example 7.4 shows the definition of the Account component interface, which is a local interface:

Code Example 7.4 Account Interface
 public interface Account extends javax.ejb.EJBLocalObject {    double getBalance();    void credit(double amount);    void debit(double amount) throws InsufficientFundsException;    ... } 

Had the AccountEJB bean implemented a remote client view, each of the Account component interface methods would throw java.rmi.RemoteException in addition to its other exceptions.

Code Example 7.5 illustrates using the component interface for a bean with a local client view:

Code Example 7.5 Using the Component Interface
 // Somehow obtain a reference to an Account object. Account acct = ...; // Invoke business methods. double balance = acct.getBalance(); acct.debit(200.00); acct.credit(300.00); // Obtain the primary key. AccountKey pk = (AccountKey)acct.getPrimaryKey(); // Obtain the home interface. AccountHome home = (AccountHome) acct.getEJBHome(); // Pass the entity object as a parameter in a method call. // (Foo is an enterprise bean's local home or component interface.) Foo foo = ...;    // Foo foo.someMethod(acct, ...); // Remove the entity object. acct.remove(); 

7.1.3 Primary Key and Object Identity

Every entity object has an identity unique within the scope of its home interface. The primary key determines this identity. If two entity objects with the same home interface have the same primary key, they are considered identical entity objects. If they have a different primary key, they are considered different entity objects.

A client can test whether two entity object references refer to the same entity object by using the isIdentical method. The following code segment illustrates using the isIdentical method to compare two object references to determine whether they are identical:

 Account acct1 = ...; Account acct2 = ...; if (acct1.isIdentical(acct2)) {       // acct1 and acct2 refer to the same entity object } else {       // acct1 and acct2 refer to different entity objects } 

Alternatively, if it obtains two entity object references from the same home interface, the client can determine if these objects are identical by comparing their primary keys:

 AccountHome accountHome = ...; Account acct1 = accountHome.findOneWay(...); Account acct2 = accountHome.findAnotherWay(...); if (acct1.getPrimaryKey().equals(acct2.getPrimaryKey())) {       // acct1 and acct2 refer to the same entity object } else {       // acct1 and acct2 refer to different entity objects } 

Note that comparing primary keys is valid only when comparing objects obtained from the same home interface. When objects are obtained from different home interfaces, the client must use the isIdentical method on one of the objects to perform the comparison.

7.1.4 Entity Object Life Cycle

Figure 7.1 illustrates an entity object's life cycle, as seen from the perspective of a client. In the diagram, the term referenced means that the client holds an object reference for the entity object. The figure illustrates the following points about an entity object's life cycle:

  • Creating an entity object

    • A client can create an entity object by invoking a create method defined in the entity bean's home interface.

    • It is possible to create an entity object without involving the entity bean or its container. For example, using a direct database insert can create the representation of the entity object's state in the resource manager that is, in the database.

    • Finding an entity object A client can look up an existing entity object by using a find method defined in the home interface.

    • Invoking business methods A client that has an object reference for the entity object can invoke business methods on the entity object.

    • Understanding the life cycle The life cycle of the entity object is independent of the life cycle of the client-held object references. This means that an entity object is not removed when it is no longer referenced by a client. Likewise, the existence of an object reference does not ensure the existence of the entity object.

  • Removing an entity object

    • A client can remove an entity object by using one of the remove methods defined in the home and component interfaces. If a client attempts to invoke a business method on an entity object after the object has been removed, the client receives NoSuchObjectException.

    • It is possible to remove an entity object without involving the entity bean or its container. For example, using a direct database delete can remove the representation of the entity object's state from the resource manager: the database. If a client attempts to invoke a business method on an entity object after its state has been removed from the database, the client receives NoSuchObjectLocalException (or NoSuchObjectException if a remote client).

Figure 7.1. Client View of an Entity Object Life Cycle

graphics/07fig01.gif

Entity objects are considered to be, in general, persistent objects. An entity object can be accessed concurrently through multiple JVMs. The lifetime of an entity object is not limited by the lifetime of the JVM process in which the entity bean instances execute.

Although the crash of the JVM may result in the rollback of current transactions, it does not destroy previously created entity objects; nor does it invalidate the references to the component and home interfaces held by clients.

An entity object remains accessible to its clients as long as the representation of its state is maintained in the resource manager or until a reconfiguration of the bean or container invalidates the object references and handles held by the clients. This can happen, for example, when the entity bean is uninstalled from the container or if the container is reconfigured to listen on a different network address.

Multiple clients can access the same entity object concurrently. If so, the container uses transactions to isolate the clients' work from one another. This is explained in Section 7.2.6, Concurrent Invocation of an Entity Object, on page 233.



Applying Enterprise Javabeans
Applying Enterprise JavaBeans(TM): Component-Based Development for the J2EE(TM) Platform
ISBN: 0201702673
EAN: 2147483647
Year: 2003
Pages: 110

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