bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Programming WebLogic Enterprise JavaBeans

Designing EJBs

The following sections provide guidelines for designing WebLogic Server Enterprise JavaBeans (EJB)s. Some suggestions apply to remote object models and Remote Method Invocation (RMI) as much as they do to EJB.

- Designing Session Beans

- Designing Entity Beans

- Designing Message-Driven Beans

- Using WebLogic Server Generic Bean Templates

- Using Inheritance with EJBs

- Accessing Deployed EJBs

- Preserving Transaction Resources

Designing Session Beans

One way to design session beans is to use the model-view design. The view is the graph-user interface (GUI) form and the model is the piece of code that supplies data to the GUI. In a typical client-server system, the model lives on the same server as the view and talks to the server.

Have the model reside on the server, in the form of a session bean. (This is analogous to having a servlet providing support for an HTML form, except that a model session bean does not affect the final presentation.) There should be one model session bean instance for each GUI form instance, which acts as the form's representative on the server. For example, if you have a list of 100 network nodes to display in a form, you might have a method called getNetworkNodes() on the corresponding EJB that returns an array of values relevant to that list.

This approach keeps the overall transaction time short, and requires minimal network bandwidth. In contrast, consider an approach where the GUI form calls an entity EJB finder method that retrieves references to 100 separate network nodes. For each reference, the client must go back to the datastore to retrieve additional data, which consumes considerable network bandwidth and may yield unacceptable performance.

Designing Entity Beans

Reading and writing RDBMS data via an entity bean can consume valuable network resources. Network traffic may occur between a client and WebLogic Server, as well as between WebLogic Server and the underlying datastore. Use the following suggestions to model entity EJB data correctly and avoid unnecessary network traffic.

Entity Bean Home Interface

The container provides an implementation of the home interface for each entity bean deployed in the container and it makes the home interface accessible to the clients through JNDI. An object that implements an entity beans's home interface is called an EJBHome object. The entity bean's home interface enables a client to do the following:

- Use the create() methods to create new entity objects within the home.

- Use the finder() methods to find existing entity objects within the home.

- Use the remove() methods to remove an entity object from the home.

- Execute a home method that is not specific to a particular entity bean instance.

Make Entity EJBs Coarse-Grained

Do not attempt to model every object in your system as an entity EJB. In particular, small subsets of data consisting of only a few bytes should never exist as entity EJBs, because the trade-off in network resources is unacceptable.

For example, cells in a spreadsheet are too fine-grained and should not be accessed frequently over a network. In contrast, logical groupings of an invoice's entries, or a subset of cells in a spreadsheet can be modeled as an entity EJB, if additional business logic is required for the data.

Encapsulate Additional Business Logic in Entity EJBs

Even coarse-grained objects may be inappropriate for modeling as an entity EJB if the data requires no additional business logic. For example, if the methods in your entity EJB work only to set or retrieve data values, it is more appropriate to use JDBC calls in an RDBMS client or to use a session EJB for modeling.

Entity EJBs should encapsulate additional business logic for the modeled data. For example, a banking application that uses different business rules for "Platinum" and "Gold" customers might model all customer accounts as entity EJBs; the EJB methods can then apply the appropriate business logic when setting or retrieving data fields for a particular customer type.

Optimize Entity EJB Data Access

Entity EJBs ultimately model fields that exist in a data store. Optimize entity EJBs wherever possible to simplify and minimize database access. In particular:

- Limit the complexity of joins against EJB data.

- Avoid long-running operations that require disk access in the datastore.

- Ensure that EJB methods return as much data as possible, so as to minimize round-trips between the client and the datastore. For example, if your EJB client must retrieve data fields, use bulk get/setAttributes() methods to minimize network traffic.

Designing Message-Driven Beans

A message-driven bean acts as a message consumer in the WebLogic JMS messaging system. For more information on designing message-driven beans, see Designing Message-Driven Beans.

Using WebLogic Server Generic Bean Templates

For each EJB type, WebLogic Server provides a generic class that contains Java callbacks, or listeners, that are required for most EJBs. The generic classes are in the weblogic.ejb package:

- GenericEnterpriseBean

- GenericEntityBean

- GenericMessageDrivenBean

- GenericSessionBean

You can implement a generic bean template in a class of your own by importing the generic class into the class you are writing. This example imports the GenericSessionBean class into HelloWorldEJB:

import weblogic.ejb.GenericSessionBean;
...
public class HelloWorldEJB extends GenericSessionBean {

Using Inheritance with EJBs

Using inheritance may be appropriate when building groups of related beans that share common code. However, be aware of several inheritance restrictions apply to EJB implementations.

For bean-managed entity EJBs, the ejbCreate() method must return a primary key. Any class that inherits from the bean-managed EJB class cannot have an ejbCreate() method that returns a different primary key class than does the bean-managed EJB class. This restriction applies even if the new class is derived from the base EJB's primary key class. The restriction also applies to the bean's ejbFind() method.

Also, EJBs inheriting from other EJB implementations change the interfaces. For example, the following figure shows a situation where a derived bean adds a new method that is meant to be accessible remotely.

Figure 2-1 Derived bean (BBean) adding new method to be accessible remotely

An additional restriction is that because AHome.create() and BHome.create() return different remote interfaces, you cannot have the BHome interface inherit from the AHome interface. You can still use inheritance to have methods in the beans that are unique to a particular class, that inherit from a superclass or that are overridden in the subclass. See the EJB 1.1 subclass Child example in the and classes in the WebLogic Server distribution for an examples of inheritance.

Accessing Deployed EJBs

WebLogic Server automatically creates implementations of an EJB's home and remote interfaces that can function remotely. This means that all clients — whether they reside on the same server as the EJB, or on a remote computer — can access deployed EJBs in a similar fashion.

All EJBs must specify their environment properties using Java Naming and Directory Interface (JNDI). You can configure the JNDI name spaces of EJB clients to include the home EJBs that reside anywhere on the network — on multiple machines, application servers, or containers.

However, in designing enterprise application systems, you must still consider the effects of transmitting data across a network between EJBs and their clients. Because of network overhead, it is still more efficient to access beans from a "local" client — a servlet or another EJB — than to do so from a remote client where data must be marshalled, transmitted over the network, and then unmarshalled.

Differences Between Accessing EJBs from Local Clients and Remote Clients

One difference between accessing EJBs from local clients and remote clients is in obtaining an InitialContext for the bean. Remote clients obtain an InitialContext from the WebLogic Server InitialContext factory. WebLogic Server local clients generally use a getInitialContext method to perform this lookup, similar to the following excerpt:

Figure 2-2 Code sample of a local client performing a lookup

>     ...
>     Context ctx = getInitialContext("t3://localhost:7001", "user1", "user1Password");
>     ...
>     static Context getInitialContext(String url, String user, String password) {

>        Properties h = new Properties();
>        h.put(Context.INITIAL_CONTEXT_FACTORY,
>           "weblogic.jndi.WLInitialContextFactory");
>        h.put(Context.PROVIDER_URL, url);
>        h.put(Context.SECURITY_PRINCIPAL, user);
>     h.put(Context.SECURITY_CREDENTIALS, password);

>        return new InitialContext(h);

>     }

Internal clients of an EJB, such as servlets, can simply create an InitialContext using the default constructor, as shown here:

>     Context ctx = new InitialContext();

Restrictions on Concurrency Access of EJB Instances

Although database concurrency is the default and recommended concurrency access option, multiple clients can use the exclusive concurrency option to access EJBs in a serial fashion. Using this exclusive option means that if two clients simultaneously attempt to access the same entity EJB instance (an instance having the same primary key), the second client is blocked until the EJB is available. For more information on the database concurrency option, see Exclusive Concurrency Strategy.

Simultaneous access to a stateful session EJB results in a RemoteException. This access restriction on stateful session EJBs applies whether the EJB client is remote or internal to WebLogic Server. However, you can set the allow-concurrent-calls option to specify that a stateful session bean instance will allow concurrent method calls.

If multiple servlet classes access a session EJB, each servlet thread (rather than each instance of the servlet class) must have its own session EJB instance. To avoid concurrent access, a JSP/servlet can use a stateful session bean in request scope.

Storing EJB References in Home Handles

Once a client obtains the EJBHome object for an EJB instance, you can create a handle to the home object by calling getHomeHandle(). getHomeHandle() returns a HomeHandle object, which can be used to obtain the home interface to the same EJB at a later time.

A client can pass the HomeHandle object as arguments to another client, and the receiving client can use the handle to obtain a reference to the same EJBHome object. Clients can also serialize the HomeHandle and store it in a file for later use.

Using Home Handles Across a Firewall

By default, WebLogic Server stores its IP address in the HomeHandle object for EJBs. This can cause problems with certain firewall systems. If you cannot locate EJBHome objects when you use home handles passed across a firewall, use the following steps:

1. Start WebLogic Server.

2. Start the WebLogic Server Administration Console.

3. From the left pane, expand the Servers node and select a server.

4. In the right pane, select the Configuration tab for that server and then the Network tab.

5. Check the Reverse DNS Allowed box to enable reverse DNS lookups.

When you enable reverse DNS lookups, WebLogic Server stores the DNS name of the server, rather than the IP address, in EJB home handles.

Preserving Transaction Resources

Database transactions are typically one of the most valuable resources in an online transaction-processing system. When you use EJBs with WebLogic Server, transaction resources are even more valuable because of their relationship with database connections.

WebLogic Server can use a single connection pool to service multiple, simultaneous database requests. The efficiency of the connection pool is largely determined by the number and length of database transactions that use the pool. For non-transactional database requests, WebLogic Server can allocate and deallocate a connection very quickly, so that the same connection can be used by another client. However, for transactional requests, a connection becomes "reserved" by the client for the duration of the transaction.

To optimize transaction use on your system, always follow an "inside-out" approach to transaction demarcation. Transactions should begin and end at the "inside" of the system (the database) where possible, and move "outside" (toward the client application) only as necessary. The following sections describe this rule in more detail.

Allowing the Datastore to Manage Transactions

Many RDBMS systems provide high-performance locking systems for Online Transaction Processing (OLTP) transactions. With the help of Transaction Processing (TP) monitors such as Tuxedo, RDBMS systems can also manage complex decision support queries across multiple datastores. If your underlying datastore has such capabilities, use them where possible. Never prevent the RDBMS from automatically delimiting transactions.

Using Container-Managed Transactions Instead of Bean-Managed Transactions for EJBs

Your system should rarely rely on bean-managed transaction demarcation. Use WebLogic Server container-managed transaction demarcation unless you have a specific need for bean-managed transactions.

Possible scenarios where you must use bean-managed transactions are:

- You define multiple transactions from within a single method call. WebLogic Server demarcates transactions on a per-method basis.

  Note: However, instead of using multiple transactions in a single method call, it is better to break the method into multiple methods, with each of the multiple methods having its own container-managed transaction.

- You define a single transaction that "spans" multiple EJB method calls. For example, you define a stateful session EJB that uses one method to begin a transaction, and another method to commit or roll back a transaction.

  Note: Avoid this practice if possible because it requires detailed information about the workings of the EJB object. However, if this scenario is required, you must use bean-managed transaction coordination, and you must coordinate client calls to the respective methods.

Never Demarcate Transactions from Application

In general, client applications are not guaranteed to stay active over long periods of time. If a client begins a transaction and then exits before committing, it wastes valuable transaction and connection resources in WebLogic Server. Moreover, even if the client does not exit during a transaction, the duration of the transaction may be unacceptable if it relies on user activity to commit or roll back data. Always demarcate transactions at the WebLogic Server or RDBMS level where possible.

For more information on demarcating transaction see Transaction Management Responsibilities.

Always Use A Transactional Datasource for Container-Managed EJBs

If you configure a JDBC datasource factory for use with container-managed EJBs, make sure you configure a transactional datasource (TXDataSource) rather than a non-transactional datasource (DataSource). With a non-transactional datasource, the JDBC connection operates in auto commit mode, committing each insert and update operation to the database immediately, rather than as part of a container-managed transaction.