Stateful Session Beans
Stateful session beans are session beans that preserve some state within the EJB specifically associated with its EJB client. The state (a.k.a. conversational state) of a stateful session bean refers to the data stored within the fields (that is, variables) of the bean instance, as well as within any objects the bean holds and those objects' fields and objects, and so on. When an EJB client accesses a stateful session bean at one instant and changes the state of the bean instance, that state must be preserved and assumed by the bean instance at some later instant in which the bean is accessed.
By creating a session bean that is stateful, the container must assume more responsibility and care in how it manages the bean. For starters, stateful session bean instances are associated with clients that create them and therefore cannot simply be plucked at random from a pool to service client requests. In fact, the creation and removal of a stateful session bean by a client is directly related to the creation and removal of stateful session bean instances on the server side. Furthermore, when resources become limited, a container may decide to serialize (that is, passivate) one or more stateful session beans to persistent storage. As resources become available, or, perhaps, upon client request, the passivated bean must be activated and brought into active memory. Thus, stateful session beans require additional special design considerations on the part of the bean developer.
Stateful Session Bean Logical Component Architecture
Figure 2 depicts the basic architecture (ala another UML class diagram) involved in creating stateful session bean components.
Figure 2 Stateful session EJBs.
Public, nonfinal, and nonabstract stateful session bean implementations, such as MyStatefulSessionEJBean, must implement the SessionBean interface, which, in turn, extends the EnterpriseBean interface. Stateful session EJBs also implement public, nonfinal, and nonstatic business-specific methods, such as the someMethod() and anotherMethod() sample methods shown in the figure. As a final note, session bean implementations must also have a public parameterless constructor and should not implement the finalize() method. Finally, stateful session beans may optionally implement the javax.ejb.SessionSynchronization interface to enable the bean to be notified of certain transaction management events.
Stateful Session Bean Interfaces
Because state is important for stateful session beans, the initial state in which such a bean is created could be important. Thus, stateful session beans can be defined with one or more ejbCreate(...) methods that take zero or more input parameters and return a void type. The exact parameters that are passed into such methods are application-specific, but the name of the method must be ejbCreate. Unlike the ejbCreate() invocation on a stateless session bean, stateful session bean ejbCreate() methods are bound to the EJB client that will continue to use that specific EJB instance. Note also that the container calls setSessionContext() on the stateful session bean before any ejbCreate() method is called, as was the case with the stateless session bean.
The invocation of an ejbRemove() method implemented by a session bean indicates that the client to which this session belongs has decided to remove the stateful session bean from servicing any more requests. The container may also invoke ejbRemove() on a bean when a configurable session maximum timeout has expired.
Perhaps the most significant things to consider when designing a stateful session bean are the ramifications of passivation and activation on your bean. As stated earlier, a container passivates your session bean by serializing its contents and writing this information to some persistent storage mechanism. A container does this when active memory resources are becoming scarce and usually employs some sort of least recently used algorithm to determine which specific bean instances should be passivated (although the actual algorithm used is vendor-specific).
Before a container passivates your bean instance, it calls ejbPassivate() on your bean, which your bean must implement. The implementation of ejbPassivate() must clean up any resources that cannot be serialized and persisted, such as database connections and open file handles. Any objects that remain unclosed after ejbPassivate() completes must be passivatable by the container.
When a request for a passivated bean is made, or, perhaps, when resources are again freed, the container activates the bean. That is, the container deserializes the persisted state of the bean and reconstructs the bean in active memory with the state in which it was originally persisted. After the bean state is reconstructed, the container calls ejbActivate() on the stateful session bean implementation, which should reconstruct any resources that were closed during the call to ejbPassivate(). Alternatively, if a certain amount of time has expired while the bean was in persistent storage, the vendor may elect to remove the bean from persistent storage, given some configurable time limit.