|
Kevin Boone, Web-Tomorrow
This article describes the lifecycles of the various types of enterprise JavaBean (EJB). It is intended as a guide to help EJB developers understand exactly how their EJBs will be interacting with the EJB container. It aims also to clear up some of the widespread misunderstandings about which EJB methods get called in which circumstances. This document is based on the 1.1 version of the EJB specification. Session EJBSession EJBs are intended to represent some kind of service provided to a client, rather than being a model of some entity in the business domain. Session EJBs have a relatively short lifespan, usually no longer than the duration of a particular client-provider interaction. The EJB specification does not stipulate that the state of an EJB should be able to persist in the event of a system failure, although some container providers may have a system to enable this. In any event, a session EJB will normally have a lifespan measured in seconds or minutes, rather that days or years.Session EJBs come in two varieties: stateful and stateless. The stateless variety is the simpler, and it has absolutely no conversational state. From the client perspective, every interaction with a stateless session EJB must be complete and self-contained in a single method call. There is no guarantee that if the client calls a different method, or even the same method twice, the method will be called on the same instance of the EJB class. In practice, the container will normally maintain a pool of stateless session beans, and each method call will be dispatched to a free instance in the pool. Stateful session EJBs do have a conversational state; once instantiated each instance is associated with a particular client. The client does have create/destroy control over the EJB instance, but the container may also destroy the instance if it detects that it is unused. Whether a session EJB is stateful or stateless, the EJB specification dictates that any instance of the EJB can only serve one client at a time. That is, session EJBs are (by design) not re-entrant. If a client gets the remote interface to a session EJB, and calls methods on it in two different threads, this will result in an exception being thrown. The two threads should each get a reference to a remote interaface by calling create on the home interface.
Stateless session EJBThe lifecycle of a stateless session EJB is shown in the state diagram below. Note that these states are of the EJB instance loaded in the container.
Stateless session EJBs are not associated with a particular client. The container can maintain a pool of them, and direct method invocations to any free instances. Therefore, creation and deletion of instances has little connection with the client. When a client calls create() on the home interface, the container need not do anything in particular to any EJB instance. The container must ensure that, when a business method is called, there is at least one instance in the pool. Similarly, the container will delete instances when it sees fit.
Stateless session EJBs cannot be activated or passivated (as they have no state to save). They cannot take part in transactions in any sense that requires programmatic support (e.g., they cannot implement SessionSynchronization because there is no code to synchronize. Therefore, the stateless session has a very simple lifecycle.
Stateful session EJBIn sharp contrast, the stateful session EJB probably has the most complex lifecycle. This is because it provides programmatic support for transaction monitoring via theSessionSynchronization
interface.
The stateful session EJB is associated with a particular client, and will be created and destroyed
(indirectly) at the behest of the client. Moreover, because it may persist for some time, it provides an activation/passivation mechanism. Note that the instance may be activated to serve a different client than the one it was talking to when it was passivated. This means that the passivate method must leave the EJB in a state at which the container can serialize it.
Method calls may be transactional or non-transactional (according to the deployment descriptor). A non-transactional method can be satisfied immediately, and does not involve the SessionSynchronization methods. Note that the container can activate a passivated session to serve a particular method call, if there is no active session currently available.
If a method is transactional, then the EJB container interacts with a transaction manager. Transactions are committed when the method returns, but bear in mind that the method may call other methods, but the SessionSynchronization methods are only called at the beginning and end of a complete transaction.
Entity EJBThe entity bean represents some form of persistent entity in the business domain, and very often maps onto a row of a database table. In the state diagram below, the lifecycle shown is that of the EJB instance in the container; the database row with which it may be associated has a separated lifecycle.
Note that entity EJBs do not have a conversational state with a client. They are persistent, but not sessional. Thus the container can (and probably will) maintain a pool of EJBs, and associate each with a particular database item when referenced by a client. The ejbActivate() and ejbPassivate() methods are called when the container has changed the mapping of the instance onto the databse; unlike with session EJBs, the entity need not free resources when passivated, or reclaim them
when activated.
The container associates the instance with a data item when the client calls create(...)
on the home interface, or calls a business method on the remote interface. It does not
do so when the client calls findByPrimaryKey(), or any other finder method. Note on the diagram that the `findXXX' event does not cause a transition to the `ready' state.
Although entity EJB methods may be transactional, there is no programmatic control of transactions, andtransactional progress is not part of the lifecycle. When an EJB instance is in the `ready' state, the container will call ejbLoad() and
ejbStore() where necessary to store and load the instance variables to the persistent
store. The sequence and frequency with which it does this depends on the `commit option' supported by the container. Typically the container will call ejbLoad() before each business method,
and ejbStore() after.
EJB gotchasEJB development is complicated by the architecture in which an EJB operates. Here are some of the common problems that developers should be aware of. A familiarity with the lifecycle of each of the different EJB types can help to avoid making the following mistakes.Re-entrancySessionBeans are intentionally non-reentrant; the EJB container will thow aRemoteException if a client tries to call methods on the same remote interface with two different threads. Given that a session bean is intended to represent a conversational interaction with a single client, the specification that they be nonre-entrant is logical. Entity beans can, however, be re-entrant if so specified.
If an entity bean is specified as being re-entrant, then multiple threads will be allowed concurrent access to the same methods in the same instances. However, the specification recommends that this not be allowed, unless it is essential. Inconsistent use of termsIn the EJB specification, and the EJB API, the same terms are used to mean somewhat different things. A good example is the use of the terms `activation' and `passivation'; these terms mean different things to session and entity EJBs. For a session EJB, the container callsejbPassivate() to reclaim resources that the session may be holding. The EJB should respond by freeing resources, but in such a manner that they can be reinstated when ejbActivate is called. An entity EJB, on the other hand, is created initially in the passive state. It interprets this to mean that the bean instance is not assoicated with any particular business data (i.e., no particular database row). The container calls ejbActivate() when the association is made between the EJB instance and the business data. In entity beans, activation and passivation are only loosely associated with resource management.
Widespead misconceptions about the specificationThe EJB specification has gone through several revisions, and many people are still using code that complied strictly with earlier versions, and does not comply with recent revisions. For example, the current version of the EJB 1.1 specification (page 52) specifically states that an EJB must not store its context in a transient instance variable. And yet, lines like this:private transient EntityContext ctx;appear at the start of many EJB classes. Here are some similar examples.
Use of the same interfaces to specify behaviour in logically different classesWhen implementing an EJB class, the code will specify that the class impements one of the EJB interfaces, eitherSessionBean or EntityBean. The fact that these interfaces are implemented means that the specified methods must be provided by the developer. However, there is no guarantee that any of them will be called. The needs of a stateless session EJB are somewhat different to those of a stateful session, but they implement the same interfaces. In addition, the EJB must provide other methods which are not specified in the interface, but will be called (e.g., ejbCreate()). The section below summarises the methods that must be implemented in each of the EJB types, and when they will be called, if ever.
Summary of EJB-class method requirementsWhen implementing an EJB class, the code will specify that the class impements one of the EJB interfaces, eitherSessionBean or EntityBean. The fact that these interfaces are implemented means that the specified methods must be provided by the developer. However, there is no guarantee that any of them will be called. In addition, the EJB must provide other methods which are not specified in the interface, but will be called (e.g., ejbCreate()). The table below shows the methods that must be implemented in each of the EJB types, and when they will be called, if ever.
|
©1994-2003 Kevin Boone, all rights reserved