BEA Logo BEA WebLogic Server Release 1.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

   BEA WebLogic Server Enterprise JavaBeans:   Previous topic   |   Next topic   |   Contents   

 

WebLogic Server EJB Design and Development

 

Overview

Invoking deployed EJBs

Local vs. remote clients

Restrictions for accessing EJB instances

Storing EJB references in home handles

Using home handles across a firewall

EJB Design Tips

Preserve transaction resources

Allow the datastore to manage transactions

Use container-managed transactions over bean-managed transactions

Never demarcate transactions from a client application

Use correct modeling for entity EJBs

Entity EJBs should be coarse-grained

Entity EJBs should contain business logic

Optimize entity EJB data access

Use isModified() where appropriate

Using inheritance with EJBs

Using Session Beans

Overview

This section provides a collection of design tips and debugging points to keep in mind when building applications with Enterprise JavaBeans. A number of these tips apply to remote object models (RMI and CORBA) as much as they do to EJB.

Invoking deployed EJBs

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

With the EJB 1.1 specification, all EJBs must specify their environment properties using JNDI. EJB clients can configure their JNDI name spaces 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. Due to 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 serialized, transmitted over the network, and then unmarshalled.

Local vs. remote clients

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

...

Context ctx = getInitialContext("http://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);

    return new InitialContext(h);

}

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

Context ctx = new InitialContext();

Restrictions for accessing EJB instances

Entity EJBs can be accessed by multiple clients, but only in a serial fashion. If two clients attempt to access the same entity EJB instance (an instance having the same primary key), the second client blocks until the EJB is available.

An instance of a stateful session EJB can be accessed from only one client virtual machine at a time. Multiple client threads from the same virtual machine can access the same instance of a stateful session EJB, but they must do so in a serial fashion; simultaneous access to a stateful session EJB results in a RemoteException, as required by the EJB 1.1 specification.

This restriction for stateful session EJBs applies whether the EJB client is remote or internal to WebLogic Server. 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 RemoteException errors in such a scenario, each servlet should store a reference to a particular EJB instance in a local variable of the servlet's service() method.

Storing EJB references in home handles

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

A client can pass the HomeHandle object as arguments to another client, and the receiving client can use 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 are unable to locate EJBHome objects using home handles passed across a firewall, set the following property in your weblogic.properties file:

weblogic.system.enableReverseDNSLookups=true

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

EJB Design Tips

The following sections describe design tips that you should observe when developing and deploying EJBs on your system.

Preserve transaction resources

Database transactions are typically one of the most valuable resources in an online transaction-processing system. When using EJBs with WebLogic Server, transaction resources are even more valuable due to 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 an 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.

Allow the datastore to manage transactions

Many RDBMS systems provide high-performance locking systems for 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. You should never prevent the RDBMS from automatically delimiting transactions.

Use container-managed transactions over bean-managed transactions

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 may need bean-managed transactions are:

Never demarcate transactions from a client 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 rollback data. Always demarcate transactions at the WebLogic Server or RDBMS level where possible.

Use correct modeling for entity EJBs

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 correctly model entity EJB data and avoid unnecessary network traffic.

Entity EJBs should be coarse-grained

You should 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, as the trade-off in network resources is unacceptable.

For example, line items in an invoice or 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 may be modeled as an entity EJB, if additional business logic is required for the data.

Entity EJBs should contain business logic

Even coarse-grained objects may be inappropriate for modelling 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 use JDBC calls in an RDBMS client or use a session EJB.

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. You should optimize entity EJB wherever possible to simplify and minimize database access. In particular:

Use isModified() where appropriate

Use the isModified() method in entity EJBs to eliminate unnecessary database writes for read-only operations. See Using is-modified-method-name to limit calls to ejbStore() for more information.

Using inheritance with EJBs

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

For bean-managed 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. 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.

Additional restrictions exist for EJBs where inheriting another EJB implementation changes the interface. For example, the following table describes a situation where a derived bean adds a new method that is meant to be accessible remotely:

Bean

Method

Interface

Method

ABean

afoo()

ARemote

afoo()

BBean (extends ABean)

bfoo()

BRemote

bfoo()

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 example Enterprise JavaBean subclass Child example packages and classes.

Using Session Beans

In the Model-View-Controller pattern, the view is the GUI form and the model is the piece of code that supplies data to the screen. In a typical client-server system, the model lives on the same server as the view and talks to the server.

It is better to 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.) With this design 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 which 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 of the references, the client must go back to the datastore to retrieve additional data, which consumes considerable network bandwidth and may yield unacceptable performance.