JBoss EJB 3.0 and Extensitions

  Stateful Session Bean
Introduction

The stateful session bean is a session bean that maintains its internal states. If the client invokes method calls against the same bean stub, the calls are always tunneled to the same bean instance in the container. So, all field variables in the bean instance retain their values as long as the client application retains the bean stub (or reference for a local client). The stateful session bean is typically used to track states in an application:

  • In a web application, the servlet (or JSP page) caches the bean stub as an attribute in the HttpSession object. The HTTP session's state is therefore tracked and stored in the bean instance.
  • In a rich client Java application (e.g., Swing application), the application determines what is a "session" and caches the stateful session bean stub accordingly.
The sample application

In this trail, let's implement an investment calculator application that keeps track of past calculations in the same session. Within a web session, every time the JSP page is accessed, it retrieves the same calculator bean stub, and hence loads the session history data from the same bean instance in the EJB 3.0 container.

Interface with state properties

The Calculator interface is the local business interface for this session bean. Notice that we added methods to access session state properties in the bean. The <Integer> and <Double> elements specify the type of objects in the ArrayList. An introduction to generics in JDK 1.5 can be found on Sun's web site.


public interface Calculator {

  public double calculate (int start, int end, 
                  double growthrate, double saving);

  public ArrayList <Integer> getStarts ();
  public ArrayList <Integer> getEnds ();
  public ArrayList <Double> getGrowthrates ();
  public ArrayList <Double> getSavings ();
  public ArrayList <Double> getResults ();

}
The stateful session bean implementation

The implementation of the stateful bean StatefulCalculator is straightforward. We annotated the implementation class as @Stateful and used several ArrayList objects to backup the bean properties defined in the session bean interface. The ArrayList objects are initialized for each bean instance when it is created at the beginning of a client session. Below is the complete code for the StatefulCalculator class. It is very important to note that the stateful session bean class must implement the Serializable interface so that the container can serialize them and store them to preserve the state information when the bean instances are not in use.


@Stateful
public class StatefulCalculator implements Calculator, Serializable {

  public ArrayList <Integer> starts = new ArrayList <Integer> ();
  public ArrayList <Integer> ends = new ArrayList <Integer> ();
  public ArrayList <Double> growthrates = new ArrayList <Double> ();
  public ArrayList <Double> savings = new ArrayList <Double> ();
  public ArrayList <Double> results = new ArrayList <Double> ();

  public double calculate (int start, int end, 
                           double growthrate, double saving) {
    
    // calculate the result ...
    
    starts.add(Integer.valueOf(start));
    ends.add(Integer.valueOf(end));
    growthrates.add(Double.valueOf(growthrate));
    savings.add(Double.valueOf(saving));
    results.add(Double.valueOf(result));

    return result;
  }

  public ArrayList <Integer> getStarts () {
    return starts;
  }

  // Other getter methods for the attributes ...
}
The client

In the JSP client, the StatefulCalculator bean stub is retrieved and associated with the HttpSession object so that all HTTP requests from the same session reach the same stub and hence the same bean instance in the container. The following is a code segment in the JSP page.


Calculator cal =
      (Calculator) session.getAttribute("sfsb_cal");
if (cal == null) {
  try {
    InitialContext ctx = new InitialContext();
    cal = (Calculator) ctx.lookup(
            "EJB3Trail/StatefulCalculator/local");
    session.setAttribute ("sfsb_cal", cal);
  } catch (Exception e) {
    e.printStackTrace ();
  }
}

// Make use of the cal object
Complete code reference

EJB server

EJB client

Summary

In this trail, we discussed how to use stateful session beans to track user sessions in web applications. To manage the internal state of the session bean, you need to understand an important concept: session bean life cycles. So, read on to the next trail.