users@glassfish.java.net

Re: Issue with persistence context propagation: SFSB call SLSB

From: Marina Vatkina <Marina.Vatkina_at_Sun.COM>
Date: Wed, 17 Dec 2008 13:12:09 -0800

For persistence context to be propagated, it needs to be associated with the
same transaction. If your code in a servlet is not executed in a user
transaction, the container starts a tx when you call CustomerDAO.load() and
completes it by the time the call returns to the servlet. Same will be true for
the SFSB, but because the persistence context there is extended, the
em.contains() returns true as it still holds the customer ref.

HTH,
-marina

glassfish_at_javadesktop.org wrote:
> Hi,
>
> The issue I have is with WebSphere 6.1 + EJB 3 feature pack. However the issue itself is generic so I've decided to post it here too. Hopefully somebody can share some insight into it.
>
> According to EJB 3 spec, it seems that we can call a stateless session bean method from inside a stateful session bean. But WAS 6.1 + EJB 3 feature pack does not seem to work in this aspect.
>
> Here is the detail of my test:
>
> I have a simple entity bean called Customer. A simple SLSB called CustomerDAO like this:
>
> @Stateless(name="CustomerDAO")
> public class CustomerDAOImpl implements CustomerDAO
> {
> @PersistenceContext(unitName="OrderDB")
> EntityManager em;
>
> @TransactionAttribute(TransactionAttributeType.REQUIRED)
> public Customer findCustomer(int customerId) throws CustomerDoesNotExist {
> Customer customer = (Customer) em.find(Customer.class, customerId);
> if (customer == null) {
> throw new CustomerDoesNotExist("Customer does not exist");
> }
> return customer;
> }
> ...
> }
>
> Now a SFSB:
> @Stateful(name="EditCustomerService")
> public class EditCustomerServiceImpl implements EditCustomerService
> {
> @PersistenceContext(unitName="OrderDB", type=PersistenceContextType.EXTENDED)
> EntityManager em;
>
> @EJB
> CustomerDAO customerDAO;
>
> Customer customer;
>
> @TransactionAttribute(TransactionAttributeType.REQUIRED)
> public void load(PrintWriter out)
> {
> try {
> customer = customerDAO.findCustomer(1);
> // If I comment out the line above and uncomment the line below, everything works
> //customer = (Customer) em.find(Customer.class, 1);
> out.println("customer loaded: " + customer);
> } catch (Exception ex) {
> ex.printStackTrace();
> }
> }
> @TransactionAttribute(TransactionAttributeType.SUPPORTS)
> public void edit(PrintWriter out) {
> out.println("customer edited: " + customer + ", " + customerContained);
> Date now = new Date();
> customer.setName(customer.getName() + " " + now.getTime());
> customerContained = em.contains(customer);
> out.println("customer edited: " + customer + ", " + customerContained);
> }
>
> @TransactionAttribute(TransactionAttributeType.REQUIRED)
> @Remove
> public void save(PrintWriter out) {
> // If customer is detached, I have to call merge.
> //em.merge(customer);
> // In extended PC entities are managed so I should not need to call flush
> //em.flush();
> customerContained = em.contains(customer);
> out.println("customer saved: " + customer + ", " + customerContained);
> }
> }
>
> However when EditCustomerService.load() is called from inside a servlet, customer becomes a detached object. As a result, after I call edit and save, the change made inside edit is not saved.
>
> The key is the load method. I expect when the load is called, a transaction will be started. But I'm not sure when the persistence context for the SFSB is created. It seems that it is created much later, before a new persistence context is created inside CustomerDAO.findCustomer(). I guess a new persistence context is created inside CustomerDAO.findCustomer() because there is no PC associated with the transaction when the thread enters CustomerDAO.findCustomer().
>
> I read EJB 3 spec again. It seems EJB 3 does not exactly say when an extended PC is created. It just says that an extended PC is created when the corresponding EntityManager is created and its life cycle goes with that of the SFSB itself. EJB 3 spec does not say exactly the extended PC is created. Is it created when the SFSB is constructed? Apparently not in WebSphere.
>
> Can somebody please shed some light into this?
> [Message sent by forum member 'anqingxu' (anqingxu)]
>
> http://forums.java.net/jive/thread.jspa?messageID=321655
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_glassfish.dev.java.net
> For additional commands, e-mail: users-help_at_glassfish.dev.java.net
>