Value List HandlerContextThe 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. ProblemMost 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
SolutionUse 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. StructureThe following class diagram illustrates the Value List Handler pattern.
Participants & CollaborationsThe following sequence diagram shows the interactions for the Value List Handler:
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. 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. 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. 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. 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
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. 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. 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 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. 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
This Value List Handler pattern is based on Iterator pattern described in the GoF Design Patterns book.
(c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved. Version 1.0 Beta | ||||
|
| ||||||||||||