5.6 Design Guidelines and Patterns
This chapter contrasts stateless session beans with stateful session beans. We discuss situations where each is the preferable choice for implementing an EJB. To implement the Value List Iterator Pattern, we use a stateful session bean to control a data-intensive stateless session bean.
Value List Iterator Pattern
In situations where an enterprise application requests a large amount of data, the Value List Iterator Pattern eases network load and the resource consumption caused by large data returns. Instead of receiving all the data at once, the client controls the amount by requesting data a page at a time. Furthermore, the client can control how many elements a page contains.
Our implementation of this pattern uses both a stateful bean (MusicIterator EJB) and a stateless bean (MusicPage EJB). The stateful bean keeps track of per-client data: the desired page size and the current location in the data set. It also provides client-friendly routines such as hasMoreElements() and hasPrevi-ousElements() to help with end-of-data and start-of-data boundary conditions.
Why not eliminate the MusicIterator EJB and place the paging state information in another component? If the MusicPage EJB maintains this information, it would have to be stateful. This affects performance, since the EJB container will possibly have to passivate and activate this data. What if we place the paging state information in the JSP web client? Although we can certainly do this, our attempt here is to separate business logic from the presentation layer. A stateful MusicIterator EJB allows other clients to page through the database (such as a stand-alone Java application or another web component). And because the MusicIterator EJB is decoupled from the recording data, activating and passivating the stateful MusicIterator EJB does not require much overhead.
The stateless MusicPage EJB (which the EJB container can assign to various clients as needed) performs the data-intensive job of reading the database. To make database access vendor independent, we use the DAO pattern. Depending on the timing of the client requests, it is possible for a single instance of the MusicPage EJB to service many clients.
When using a ValueListIterator, pick a page size that is appropriate for network load and transmission speed. Use a large page size with a fast network and a smaller page size for slower networks.
Stateful vs. Stateless Session Beans
We've touched on the major issues in this chapter. If a session bean must keep track of client-specific data, then you should make it a stateful session bean. Remember that a stateful session bean is tied to a single client. Because sharing instances is not possible, stateful session beans can become a resource liability within your system. There are several ways to avoid using stateful session beans.
Encapsulate client data into value objects and pass them to methods of a stateless session bean. The downside to this approach is that it puts the burden on the client to keep track of this data. However, if the data is not complicated and doesn't change much, this is a good approach. (We used this tactic with the Loan EJB in Chapter 3. Each method requires the LoanVO value object which the client creates. See Listing 3.2 on page 41.)
If you have a session bean that is expensive to create and keep around, you might be able to wrap client-specific functionality into a small, streamlined stateful session bean. This front-end bean can then forward its calls to a stateless session bean that does all the work. This is the approach we use for the stateful MusicIterator EJB as a front end to the stateless MusicPage EJB. With this approach, the EJB container can efficiently manage the stateless, more resource-intensive enterprise bean.
Implementing a session or entity bean with local access can potentially improve the performance of an enterprise application. We say potentially, because although local calls are more efficient than corresponding remote calls, EJBs with local access must execute in the same JVM as its clients. In the long run, this restriction might hedge an enterprise application's scalability, since it prohibits the distribution of local clients across machines.
JSP Web Clients
JSP programs seem like quick solutions to provide user input and presentation aspects of an enterprise application. However, you must be careful not to build too much complexity into a JSP client. The example we provide in this chapter is about as complicated as you should get. The goal is to reduce business logic and scriptlet code in JSP files and limit JSP programs to presentation issues.
That said, what other implementation strategies are helpful for creating JSP clients? Pay particular attention to JSP clients that use stateful session beans (such as the example presented in this chapter).
A JSP client that instantiates a stateful session bean should not use class-wide variables to hold client-specific state. Instead, the client should use variables declared inside the _jspService() routine (that is, in scriptlet code, not in JSP declarations).
A JSP client that instantiates a stateless session bean can use a class-wide variable. These are declared once during the life of a JSP component and can be easily shared among multiple requests.