|    Figure EJB.6-1 illustrates the life cycle of a stateful session bean instance.     Figure EJB.6-1. Life Cycle of a Stateful Session Bean Instance         The following steps describe the life cycle of a stateful session bean instance:    -  
 A session bean instance's life starts when a client invokes a  create(...)  method on the session bean's home interface. This causes the container to invoke  newInstance()  on the session bean class to create a new session bean instance. Next, the container calls  setSessionContext()  and  ejbCreate(...)  on the instance and returns the remote reference of the session object to the client. The instance is now in the method ready state.     -  
 The session bean instance is now ready for client's business methods . Based on the transaction attributes in the session bean's deployment descriptor and the transaction context associated with the client's invocation, a business method is executed either in a transaction context or with an unspecified transaction context (shown as tx method and non-tx method in the diagram). See Chapter EJB.11 for how the container deals with transactions.     -  
 A non-transactional method is executed while the instance is in the method ready state.     -  
 An invocation of a transactional method causes the instance to be included in a transaction. When the session bean instance is included in a transaction, the container issues the  afterBegin()  method on it. The  afterBegin  is delivered to the instance before any business method is executed as part of the transaction. The instance becomes associated with the transaction and will remain associated with the transaction until the transaction completes.     -  
 Session bean methods invoked by the client in this transaction can now be delegated to the bean instance. An error occurs if a client attempts to invoke a method on the session object and the deployment descriptor for the method requires that the container invoke the method in a different transaction context than the one with which the instance is currently associated or in an unspecified transaction context.     -  
 If a transaction commit has been requested , the transaction service notifies the container of the commit request before actually committing the transaction, and the container issues a  beforeCompletion  on the instance. When  beforeCompletion  is invoked, the instance should write any cached updates to the database. If a transaction rollback had been requested instead, the rollback status is reached without the container issuing a  beforeCompletion  . The container may not call the  beforeCompletion  method if the transaction has been marked for rollback (nor does the instance write any cached updates to the database).     -  
 The transaction service then attempts to commit the transaction, resulting in either a commit or rollback.     -  
 When the transaction completes, the container issues  afterCompletion  on the instance, specifying the status of the completion (either commit or rollback). If a rollback occurred, the bean instance may need to reset its conversational state back to the value it had at the beginning of the transaction.     -  
 The container's caching algorithm may decide that the bean instance should be evicted from memory (this could be done at the end of each method, or by using an LRU policy). The container issues  ejbPassivate  on the instance. After this completes, the container saves the instance's state to secondary storage. A session bean can be passivated only between transactions, and not within a transaction.     -  
 While the instance is in the passivated state, the container may remove the session object after the expiration of a timeout specified by the deployer. All object references and handles for the session object become invalid. If a client attempts to invoke the session object, the container will throw the  java.rmi.NoSuchObjectException  to the client.     -  
 If a client invokes a session object whose session bean instance has been passivated, the container will activate the instance. To activate the session bean instance, the container restores the instance's state from secondary storage and issues  ejbActivate  on it.     -  
 The session bean instance is again ready for client methods.     -  
 When the client calls  remove  on the home or remote interface to remove the session object, the container issues  ejbRemove()  on the bean instance. This ends the life of the session bean instance and the associated session object. Any subsequent attempt by its client to invoke the session object causes the  java.rmi.NoSuchObjectException  to be thrown (this exception is a subclass of  java.rmi.RemoteException  ). The  ejbRemove()  method cannot be called when the instance is participating in a transaction. An attempt to remove a session object while the object is in a transaction will cause the container to throw the  javax.ejb.RemoveException  to the client. Note that a container can also invoke the  ejbRemove()  method on the instance without a client call to  remove  the session object after the lifetime of the EJB object has expired .         Note    The container must call the  afterBegin  ,  beforeCompletion  , and  afterCompletion  methods if the session bean class implements, directly or indirectly, the  SessionSynchronization  interface. The container does not call these methods if the session bean class does not implement the  SessionSynchronization  interface.        EJB.6.6.1 Operations Allowed in the Methods of a Stateful Session Bean Class   Table EJB.6-1 defines the methods of a stateful session bean class from which the session bean instances can access the methods of the  javax.ejb.SessionContext  interface, the  java:comp/env  environment naming context, resource managers, and other enterprise beans.    If a session bean instance attempts to invoke a method of the  SessionContext  interface, and that access is not allowed in Table EJB.6-1, the container must throw the  java.lang.IllegalStateException.     If a session bean instance attempts to access a resource manager or an enterprise bean, and that access is not allowed in Table EJB.6-1, the behavior is undefined by the EJB architecture.    Table EJB.6-1. Operations Allowed in the Methods of a Stateful Session Bean      |     Bean Method     |      Bean Method Can Perform the Following Operations     |     |     Container-Managed Transaction Demarcation     |      Bean-Managed Transaction Demarcation     |     |     constructor     |     ”    |     ”    |     |     setSessionContext     |     SessionContext methods:     getEJBHome     JNDI access to java:comp/env    |     SessionContext methods:     getEJBHome     JNDI access to java:comp/env    |     |     ejbCreate      ejbRemove      ejbActivate      ejbPassivate     |     SessionContext methods:     getEJBHome, getCallerPrincipal, isCallerInRole, getEJBObject     JNDI access to java:comp/env Resource manager access Enterprise bean access    |     SessionContext methods:     getEJBHome, getCallerPrincipal, isCallerInRole, getEJBObject, getUserTransaction     UserTransaction methods JNDI access to java:comp/env Resource manager access Enterprise bean access    |     |    business method from remote interface    |     SessionContext methods:     getEJBHome, getCallerPrincipal, getRollbackOnly, isCallerInRole, setRollbackOnly, getEJBObject     JNDI access to java:comp/env Resource manager access Enterprise bean access    |     SessionContext methods:     getEJBHome, getCallerPrincipal, isCallerInRole, getEJBObject, getUserTransaction     UserTransaction methods JNDI access to java:comp/env Resource manager access Enterprise bean access    |     |     afterBegin      beforeCompletion     |     SessionContext methods:     getEJBHome, getCallerPrincipal, getRollbackOnly, isCallerInRole, setRollbackOnly, getEJBObject     JNDI access to java:comp/env Resource manager access Enterprise bean access    |     N/A (a bean with bean-managed transaction demarcation cannot implement the  SessionSynchronization  interface)    |     |     afterCompletion     |     SessionContext methods:     getEJBHome, getCallerPrincipal, isCallerInRole, getEJBObject     JNDI access to java:comp/env    |        Notes:    -  
 The  ejbCreate  ,  ejbRemove  ,  ejbPassivate  , and  ejbActivate  methods of a session bean with container-managed transaction demarcation execute with an unspecified transaction context. Refer to Section EJB.11.6.3 for how the Container executes methods with an unspecified transaction context.        Additional restrictions:     The reasons for disallowing the operations in Table EJB.6-1 follow:    -  
 Invoking the  getEJBObject  methods is disallowed in the session bean methods in which there is no session object identity established for the instance.     -  
 Invoking the  getCallerPrincipal  and  isCallerInRole  methods is disallowed in the session bean methods for which the container does not have a client security context.     -  
 Invoking the  getRollbackOnly  and  setRollbackOnly  methods is disallowed in the session bean methods for which the container does not have a meaningful transaction context, and to all session beans with bean-managed transaction demarcation.     -  
 Accessing resource managers and enterprise beans is disallowed in the session bean methods for which the container does not have a meaningful transaction context or client security context.     -  
 The  UserTransaction  interface is unavailable to enterprise beans with container-managed transaction demarcation.        EJB.6.6.2 Dealing with Exceptions   A  RuntimeException  thrown from any method of the session bean class (including the business methods and the callbacks invoked by the container) results in the transition to the "does not exist" state. Exception handling is described in detail in Chapter EJB.12.    From the client perspective, the corresponding session object does not exist any more. Subsequent invocations through the remote interface will result in  java.rmi.NoSuchObjectException  .    EJB.6.6.3 Missed  ejbRemove()  Calls   The bean provider cannot assume that the container will always invoke the  ejbRemove()  method on a session bean instance. The following scenarios result in  ejbRemove()  not being called on an instance:    -  
 A crash of the EJB container.     -  
 A system exception thrown from the instance's method to the container.     -  
 A timeout of client inactivity while the instance is in the  passive  state. The timeout is specified by the deployer in an EJB container implementation specific way.        If the session bean instance allocates resources in the  ejbCreate(...)  method and/or in the business methods, and normally releases the resources in the  ejbRemove()  method, these resources will not be automatically released in the above scenarios. The application using the session bean should provide some cleanup mechanism to periodically clean up the unreleased resources.    For example, if a shopping cart component is implemented as a session bean, and the session bean stores the shopping cart content in a database, the application should provide a program that runs periodically and removes " abandoned " shopping carts from the database.    EJB.6.6.4 Restrictions for Transactions   The state diagram implies the following restrictions on transaction scoping of the client invoked business methods. The restrictions are enforced by the container and must be observed by the client programmer.    -  
 A session bean instance can participate in at most a single transaction at a time.     -  
 If a session bean instance is participating in a transaction, it is an error for a client to invoke a method on the session object such that the transaction attribute in the deployment descriptor would cause the container to execute the method in a different transaction context or in an unspecified transaction context. The container throws the  java.rmi.RemoteException  to the client in such a case.     -  
 If a session bean instance is participating in a transaction, it is an error for a client to invoke the  remove  method on the session object's remote or home interface object. The container must detect such an attempt and throw the  javax.ejb.RemoveException  to the client. The container should not mark the client's transaction for rollback, thus allowing the client to recover.        |