Using JDO in BMT Session Beans


In contrast to CMT, the business methods in a BMT session bean may continue to use the same persistence manager across multiple transactions. There is no need to enlist the persistence manager in the managed transaction, since the container is not managing transactions. Also in contrast to CMT, the business method in a BMT session bean can execute a series of transactions before returning. Because the persistence manager can be cached in a BMT session bean, the persistent objects that it manages can also be cached. The caching can occur directly in the bean's member fields, or it can occur indirectly in the cache belonging to the persistence manager.

In all stateless session beans, the bean is shared haphazardly with calling clients. When using a stateless session bean, the bean developer should not attempt to cache any state that depends on the sequence of calls to business methods. Consider the hypothetical example where one business method looks up and returns a Customer object, and the second business method updates the Customer object that was looked up earlier. A stateless session bean cannot store in a member field the Customer object found by the first business method for use by the second business method. With one client, the series of invocations on the bean's interface may be routed to different instances of the stateless session bean. With multiple clients, their invocations may be mixed together and routed to the same instance of the stateless session bean.

Unlike a stateless session bean, a stateful session bean is created for and assigned to one client. For this reason, it can store in a member field the Customer object from the first business method for use by the second business method.

In stateless BMT session beans, the business method must complete the transaction before it returns. On the other hand, stateful BMT session beans can allow a transaction to carry over from one business method to the next. If desired, the stateful BMT session bean can expose business methods whose sole purpose is to manage the transactional boundaries. For example, the bean may have business methods called startTransaction, commitTransaction, and rollbackTransaction to control transactional boundaries.

A Stateless BMT Session Bean

Listing 6-8 shows a QuoteServerEJB that is designed to support a stateless BMT session bean. With a few modifications that are described in the next section, it can also support the QuoteServer business interface in a stateful BMT session bean. The bean's private methods that are the same as those found in the earlier listings are omitted. This code is taken from the stateless_bmp/QuoteServerEJB.java source file in the com.ysoft.jdo.book.sayings.service.session package of the JDO Learning Tools.

Listing 6-8: Example of Stateless BMT Session Bean That Uses JDO

start example
 public class QuoteServerEJB implements SessionBean, QuoteServer    {    private SessionContext              sessionContext;    private PersistenceManagerFactory   pmf;    private PersistenceManager          pm;    private QuoteManager                qm;    private Query                       query;    public void ejbCreate() throws CreateException       {       }    public void ejbRemove()       {       cleanup();       }    public void ejbActivate()       {       }    public void ejbPassivate()       {       }    public void setSessionContext(SessionContext sc)       {       sessionContext = sc;       try          {          pmf = JndiLocator.getPMF("Std_NTR_PMF",             "com/ysoft/jdo/book/sayings/service/factory.properties");          pm = getPersistenceManager();          }       catch (Exception e)          {          throw new EJBException(                "Unable to get PMF using \"Std_NTR_PMF\" name", e);          }       }    public Quote getQuote() throws QuoteServerException       {       if (qm == null)          qm = getQuoteManager(pm, false);       if (query == null)          query = getQuery(pm);       return getQuote(pm, qm, query);       }    public void addQuote(String q, String s) throws QuoteServerException       {       q = normalizeString(q);       s = normalizeString(s);       try          {          pm.currentTransaction().begin();          if (qm == null)             qm = getQuoteManager(pm);          Quote quote = qm.newQuote(q, s);          pm.makePersistent(quote);          pm.currentTransaction().commit();          }       finally          {          if (pm.currentTransaction().isActive())             {             try                {                pm.currentTransaction().rollback();                }             catch (RuntimeException logIt)                {                // log it rather than throw it, since it                // was an earlier exception that forced the rollback                }             }          }       }    // private methods are omitted    // when identical to those in earlier listings    } 
end example

In Listing 6-8, the stateless BMT QuoteServer bean obtains its persistence manager in setSessionContext, which the EJB container calls when the bean is first created. The persistence manager remains in use for the life of the bean. It is not closed until the container calls ejbRemove. The ejbPassivate and ejbActivate methods are empty because the EJB container does not passivate stateless session beans. To avoid starting a transaction in the setSessionContext method, the bean lazily fetches and caches the QuoteManager and Query in the business methods.

To show the variations possible, the getQuote method in Listing 6-8 runs without starting a transaction. To support nontransactional access, the PersistenceManagerFactory that is stored in JNDI has the NontransactionalRead property turned on. Because getQuote runs nontransactionally, it calls the getQuoteManager method with the createIfNone parameter set to false. On the other hand, because the addQuote method adds a new persistent quote, it must use a transaction. Unlike in the CMT examples, the addQuote method must also handle the issue of rolling back the transaction if the try block fails. It does this in the finally block, after first checking that the transaction is active.

Changes Required for a Stateful BMT Session Bean

When clients use stateful session beans, the EJB container creates a bean for each client. The bean remains associated with one and only one client until either the client or the container removes it. Like stateless BMT session beans, the stateful BMT session bean can cache the persistence manager between calls to the business methods, and it can run a sequence of transactions within a business method.

The stateful BMT session bean can hold both persistent objects and unmanaged objects in its member fields. The member fields of the stateful session bean are called collectively its conversational state.

Unlike stateless session beans, stateful session beans may be passivated. In the ejbPassivate method, which the container calls just before passivation, the bean must prepare its conversational state for serialization. Some of the objects that the bean refers to in its member fields may not be serializable. Except for a few field types that receive special handling (see section 7.4.1 of the Enterprise Java-Beans Specification Version 2.0), the member fields must be serializable or set to null before passivation occurs. The PersistenceManager is not a serializable type, and it does not receive special handling. Therefore it must be closed and the bean's member field that refers to it set to null when passivation occurs.

Although the bean may passivate references to managed application data objects that are serializable, the application typically wants references to managed data objects, not to the unmanaged data objects that result from the bean's reactivation. For that reason, the bean's ejbPassivate method calls its cleanup method (unchanged from Listing 6-7) to set any member fields that refer to managed persistent objects to null.

Listing 6-9 shows the few changes to the QuoteServerEJB in Listing 6-8 that are needed to support a stateful BMT session bean. Since passivation may now occur, ejbPassivate calls the cleanup method. The ejbActivate method acquires a persistence manager, but it does not acquire a persistence manager factory. A PersistenceManagerFactory object is serializable, and therefore the reference acquired in setSessionContext is not lost during passivation. The QuoteServer business interface does not expect transactions to carry over from one business method to the next. For that reason, there are no other differences between the stateful and stateless BMT session bean implementations of the QuoteServerEJB.

Listing 6-9: Example of Stateful BMT Session Bean That Uses JDO

start example
 public class QuoteServerEJB implements SessionBean, QuoteServer    {    // state that passivation preserves    private SessionContext              sessionContext;    private PersistenceManagerFactory   pmf;    // state that passivation destroys    private transient PersistenceManager pm;    private transient QuoteManager       qm;    private transient Query              query;    // ejbCreate unchanged    // ejbRemove unchanged    // setSessionContext unchanged    public void ejbActivate()       {       pm = getPersistenceManager();       }    public void ejbPassivate()       {       cleanup();       }    // getQuote unchanged    // addQuote unchanged    // all private methods are omitted    // because they are identical to those in earlier listings    } 
end example




Using and Understanding Java Data Objects
Using and Understanding Java Data Objects
ISBN: 1590590430
EAN: 2147483647
Year: 2005
Pages: 156
Authors: David Ezzio

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net