Stateful Session Beans and Extended Persistence Contexts






Stateful Session Beans and Extended Persistence Contexts

In Chapter 5, we discussed the differences between a transaction-scoped persistence context and an extended one. The EntityManager injected into the TRavelAgentBean class with the @PersistenceContext annotation is a transaction-scoped persistence context. In Chapter 16, we will see that every method within travelAgentBean has a transaction started and ended within the scope of that method. This means that any entity bean instance you persist or fetch is detached from the persistence context at the end of the method call. Any local caching the EntityManager instance had done is lost. This is why we have to call EntityManager.merge( ) and reset the customer member variable in the travelAgentBean.updateAddress( ) method. The Customer instance we fetched in findOrCreateCustomer( ) became unmanaged at the end of the method call, and the EntityManager no longer tracked the instance for state changes.

Wouldn't it be nice if all loaded entities could remain managed after any TRavelAgentBean method call? This is exactly what an EXTENDED persistence context is used for. Stateful session beans are the only EJB component type that is allowed to inject an EXTENDED persistence context through the @PersistenceContext annotation. The extended persistence context is created and attached to the stateful bean instance before @PostConstruct . When the stateful bean instance is removed, the extended persistence context is also cleaned up. Because a stateful bean represents a conversation with a client, it makes sense to cache and manage entity instances across method invocations. Stateless and message-driven beans are pooled, and managed entity instances would easily become stale and unusable. Let's look at how the travelAgentBean class would change to use an extended persistence context:

import static javax.persistence.PersistenceContextType.EXTENDED;

@Stateful
public class TravelAgentBean implements TravelAgentRemote {

    @PersistenceContext(unitName="titan", type=EXTENDED)
    private EntityManager entityManager;

    public void updateAddress(Address addr) {
       customer.setAddress(addr);
    }
...
}

When the persistence context type is marked as EXTENDED, queried entities will remain managed and attached to the stateful session bean's EntityManager. With this setting, the updateAddress( ) method can get a little simpler, as the EntityManager.merge( ) method is no longer needed. Any extended persistence context that a stateful bean has will automatically be registered with a transaction when any transactional method is invoked. When the updateAddress( ) method completes, the EJB container will automatically commit the state changes made to customer without having to manually call the merge( ) or flush( ) method.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows