Sun Java Solaris Communities My SDN Account Join SDN
 
J2EE

Sun Java Center J2EE Patterns

 

Value List Handler

Context

The client requires a list of items from the service for presentation. The number of items in the list is unknown and can be quite large in many instances.

Problem

Most J2EE applications have a search / query requirement to search and list certain data. In some cases, such a search and query operation could yield results that can be quite large. It is impractical to return the full result set when the client's requirements are to traverse the results, rather than process the complete set. Typically, a client uses the results of a query for read-only purposes, such as displaying the result list. Often, the client views only the first few matching records, and then may discard the remaining records and attempt a new query. The search activity often does not involve an immediate transaction on the matching objects. The practice of getting a list of values represented in entity beans by calling an ejbFind method which returns a collection of remote objects, then calling each entity bean to get the value is very network expensive and considered a bad practice.

There are consequences associated with using EJB finder methods that result in large results set. Every container implementation has a certain amount of finder method overhead for creating a collection of EJBObject references. Finder method behavior performance varies depending on a vendor's container implementation. According to the EJB specification, a container may invoke ejbActivate() methods on entities found by a finder method. At a minimum, a finder method returns the primary keys of the matching entities, which the container returns to the client as a collection of EJBObject references. This behavior applies for all container implementations. Some container implementations may introduce additional finder method overhead by associating the entity bean instances to these EJBObject instances to give the client access to those entity beans. However, this is a poor use of resources if the client is not interested in accessing the bean or invoking its methods. This overhead can significantly impede application performance if the application includes queries that produce many matching results.

Forces

  • The application client needs an efficient query facility to avoid having to call the entity bean's ejbFind method and invoking each remote object returned.
  • A server-tier caching mechanism is needed to serve clients that cannot receive and process the entire results set.
  • A query that is repeatedly executed on reasonably static data can be optimized to provide faster results. This depends on the application and on the implementation of this pattern.
  • EJB finder methods are not suitable for browsing entire tables in the database or for searching large result sets from a table.
  • Finder methods may have considerable overhead when used to find large number of result objects. The container may create a large number of infrastructure objects to facilitate the finders.
  • EJB finder methods are not suitable for caching results. The client may not be able to handle the entire result set in a single call. If so, the client may need server-side caching and navigation functions to traverse the result set.
  • EJB finder methods have pre-determined query constructs and offer minimum flexibility. The EJB specification 2.0 allows a query language EJB QL for container managed entity beans. EJB QL makes it easier to write portable finders and offers great flexibility for querying.
  • Client wants to scroll forward and backward within a result set.

Solution

Use a Value List Handler to control the lookup, cache the results, and provide the results to the client in a result set whose size and traversal meets the client's requirements.

This pattern creates a ValueListHandler to provide query execution functionality and results caching. The ValueListHandler directly accesses the Data Access Object that can execute the required query. The ValueListHandler stores the results obtained from the Data Access Object as a collection of Value Objects. The client requests the ValueListHandler to provide the query results as needed. The ValueListHandler implements an Iterator [GoF] pattern to provide the solution.

Structure

The following class diagram illustrates the Value List Handler pattern.

Participants & Collaborations

The following sequence diagram shows the interactions for the Value List Handler:

  • ValueListIterator
    This interface may provide the Iterator functionality with the following example methods:
    getSize()
    : obtains the size of the result set
    currentElement()
    : obtains the current ValueObject from the list
    previousElements(int howMany)
    : obtains a collection of ValueObjects that are in the list prior to the current element
    nextElements(int howMany)
    : obtains a collection of ValueObjects that are in the list after the current element.
    resetIndex(): resets the index to the start of the list
    Depending on your needs, you can include other convenience methods to be part of the Iterator interface.
  • ValueListHandler
    This session bean implements the ValueListIterator interface. The ValueListHandler executes the required query when requested by the client. The ValueListHandler obtains the query results, which it manages in a privately held collection represented by the ValueList object. The ValueListHandler creates and manipulates the ValueList collection. When the client requests the results, the ValueListHandler obtains the ValueObjects from the cached ValueList, creates a new collection of ValueObjects, serializes the collection, and sends it back to the client. The ValueListHandler also tracks the current index and size of the list.
  • DataAccessObject
    The ValueListHandler can make use of a DataAccessObject to keep separate the implementation of the database access. The DataAccessObject provides a simple API to access the database (or any other persistent store), execute the query, and retrieve the results.
  • ValueList
    The ValueList is a collection (a list) that holds the results of the query. The results are stored as ValueObjects. If the query fails to return any matching results, then this list is empty. The ValueListHandler session bean caches ValueList to avoid repeated, unnecessary execution of the query.
  • ValueObject
    The ValueObject represents an individual record from the query's results. It is an immutable serializable object that provides a placeholder for the data attributes of each record.

 

Consequences

  • Overcome EJB Finder Method overhead
    Typically, an EJB finder method is a resource intensive and an expensive way of obtaining a list of items since it involves a number of EJBObject references. The Value List Handler implements a session bean that uses a Data Access Object to perform the query and to create a collection of value objects which match the query criteria. Because value objects have relatively low overhead compared to EJBObjects and their associated infrastructure, this pattern provides benefits when application clients require queries resulting in large result sets.
  • Server-side Caching of Query Results and Client-controlled Result Dispatching
    The result set obtained from a query execution needs to be cached when a client must display the results in small subsets rather than in one large list. However, not all browser-based clients can perform such caching. When they cannot, the server must provide this functionality. The Value List Handler pattern provides a caching facility in the Value List Handler session bean to hold the result set obtained from a query execution. The result set is a collection of value objects that can be serialized if required.
    When the client requests a collection, or a subset of a collection, the handler bean returns the requested results as a serialized collection of value objects. The client receives the collection and now has a local copy of the requested information, which the client can display or process. When the client needs an additional subset of the results, it requests the handler to return another serialized collection containing the required results. The client can process the query results in smaller, manageable chunks. The handler bean also provides the client with navigation facilities (previous and next) so that the results may be traversed forward and backward as necessary.
  • Querying flexibility
    Adding a new query may require creating a new finder method or modifying an existing method, especially when using bean-managed entity beans. (With bean-managed entity beans, the developer implements the finder methods in the bean implementation.) With a container-managed entity bean, the deployer specifies the entity bean finder methods in the bean's deployment descriptor. Changes to a query for a container-managed bean require changes to the finder method specification in the deployment descriptor. Therefore, finder methods are ill suited to handle query requirements that change dynamically. You can implement a Value List Handler to be more flexible than EJB finder methods, by providing adhoc query facilities, constructing run-time query arguments using template methods, and so forth. In other words, a Value List Handler developer can implement intelligent searching and caching algorithms without being limited by the finder methods.
  • Network Performance
    Network performance may improve because only requested data is shipped (serialized) to the client on an as needed basis, rather than all data. If the client displays the first few results and then abandons the query, the network bandwidth is not wasted since the data is cached on the server side and never sent to the client. However, if the client processes the entire result set, it makes multiple remote calls to the server for the result set. When the client knows in advance that it needs the entire result set, the handler bean can provide a method that sends the client the entire result set in a one method call, and the pattern's caching feature is not used.
  • Deferred Transaction
    Caching results on the server side and minimizing finder overhead may improve transaction management. When the client is ready to further process an entity bean, it accesses the bean within a transaction context defined by the use case. For example, a query to display a list of books uses a Value List Handler to obtain the list. When the user wants to view a book in detail, it involves the book's entity bean in a transaction.

 

Related Patterns

  • Iterator Pattern [GoF]
    This Value List Handler pattern is based on Iterator pattern described in the GoF Design Patterns book.
  • Session Façade Pattern [SJC]
    Since the Value List Handler is a session bean, it may appear as a specialized session façade. However, in isolation, it is a specialized session bean rather than a specialized Session Façade. A Session Façade has other motivations and characteristics that are explained in the Session Façade pattern and is much coarser grained.

A Note on EJB 2.0 EJB Query Language (EJB QL)

EJB 2.0 Specification, introduces a special type of finder called "Select", which is implemented for internal use in an entity bean. In addition, there is a new query language called EJB Query Language, or EJB QL, to provide queries declaratively for the finder methods and the select methods.

The EJB QL syntax for finder methods allows the query to return matching entity objects, and can expose the results of a finder method query to the clients. The syntax for select methods allows the entity bean to use the select query internally to search for dependent objects, values, and other related entity beans. By contrast, the results of a select query are available to the entity bean for its own use and are not exposed to the clients.

By using EJB QL it is possible to write portable and flexible queries for container managed entity bean. However, the drawbacks of using finders for searching large number of entity beans still remain. We therefore recommend careful consideration when designing finder methods.

(c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.

Version 1.0 Beta