[jboss-jira] [JBoss JIRA] (WFLY-2504) add lazy xpc inheritance to handle legacy case, remote client with UserTransaction fails on 2nd SFSB invocation when using extended persistence context

Scott Marlow (JIRA) jira-events at lists.jboss.org
Wed Nov 13 09:08:05 EST 2013


Scott Marlow created WFLY-2504:
----------------------------------

             Summary: add lazy xpc inheritance to handle legacy case, remote client with UserTransaction fails on 2nd SFSB invocation when using extended persistence context
                 Key: WFLY-2504
                 URL: https://issues.jboss.org/browse/WFLY-2504
             Project: WildFly
          Issue Type: Enhancement
      Security Level: Public (Everyone can see)
          Components: JPA / Hibernate
            Reporter: Scott Marlow
            Assignee: Scott Marlow
             Fix For: 9.0.0.CR1


AS5 allowed a remote client to instantiate a set of stateful session beans (e.g. SFSB1 + SFSB2) and then call the remote stateful session beans in a started user transaction (UT1).  Allow the beans invoked in the same transaction, to share the same persistence context.  

One approach might be to defer creation of the extended persistence context until the first invocation (need to verify that this is the right approach).

Currently, we support shallow + deep extended persistence context inheritance.  This will be a "lazy" variation of the deep XPC inheritance.

Some of the AS5 code is pasted below for easy reference.

{code}
public class ExtendedPersistenceContextPropagationInterceptor implements Interceptor
{
   private static final Logger log = Logger.getLogger(ExtendedPersistenceContextPropagationInterceptor.class);

   public String getName()
   {
      return this.getClass().getName();
   }

   public Object invoke(Invocation invocation) throws Throwable
   {
      log.debug("++++ LongLivedSessionPropagationInterceptor");
      StatefulContainerInvocation ejb = (StatefulContainerInvocation) invocation;
      StatefulBeanContext ctx = (StatefulBeanContext) ejb.getBeanContext();

      Map<String, EntityManager> extendedPCs = ctx.getExtendedPersistenceContexts();
      if (extendedPCs == null || extendedPCs.size() == 0)
      {
         return invocation.invokeNext();
      }

      TransactionManager tm = TxUtil.getTransactionManager();
      if (tm.getTransaction() != null)
      {
         for (String kernelname : extendedPCs.keySet())
         {
            EntityManager manager = extendedPCs.get(kernelname);
            ManagedEntityManagerFactory factory = ManagedEntityManagerFactoryHelper.getManagedEntityManagerFactory(kernelname);
            factory.registerExtendedWithTransaction(manager);
         }
      }
      return invocation.invokeNext();
   }
}
{code}

{code}
public class EJB3XPCResolver implements XPCResolver
{
   private static final Logger log = Logger.getLogger(EJB3XPCResolver.class);
   /**
    * Query the current stateful bean contexts for the specified XPC.
    */
   public EntityManager getExtendedPersistenceContext(String kernelName)
   {
      StatefulBeanContext beanContext = StatefulBeanContext.currentBean.get();

      if (beanContext != null)
      {
         EntityManager em = null;

         em = beanContext.getExtendedPersistenceContext(kernelName);
         if (em != null) {
            log.info("current SFSB has XPC with scoped pu name=" + kernelName + " on SFSB bean=" + beanContext.getContainer().getIdentifier() + beanContext.getId());
            return em;
         }
         /**
          * Look for XPC in current bean set.
          */
         log.info("looking for existing XPC with scoped pu name=" + kernelName);

         List <StatefulBeanContext> beanContexts = StatefulBeanContext.currentBean.getList();
         for( StatefulBeanContext bc : beanContexts)
         {
            em = bc.getExtendedPersistenceContext(kernelName);
            if (em != null) {
               log.info("found existing XPC with scoped pu name=" + kernelName + " on SFSB bean=" + bc.getContainer().getIdentifier() + bc.getId());
               //  Propagate created XPC as required (7.6.2.1 Inheritance of Extended Persistence Context
               beanContext.addExtendedPersistenceContext(kernelName, em);
               return em;
            }
            log.info("XPC not found yet, scoped pu name=" + kernelName + " not in SFSB bean=" + bc.getContainer().getIdentifier() + bc.getId());
         }
      }
      log.info("XPC not found scoped, search done, pu name=" + kernelName);
      return null;
   }

   @Override
   public EntityManager createExtendedPersistenceContext(String kernelName)
   {
      StatefulBeanContext beanContext = StatefulBeanContext.currentBean.get();

      if (beanContext != null)
      {
         EntityManager em = null;
         ManagedEntityManagerFactory factory=
            ((PersistenceUnitDeployment) PersistenceUnitRegistry.getPersistenceUnit(kernelName)).getManagedFactory();
         if (factory != null)
         {
            em = factory.createEntityManager();
            if (em != null)
            {
               beanContext.addExtendedPersistenceContext(factory.getKernelName(), em);
               log.info("created new XPC with scoped pu name=" + kernelName + " on SFSB bean=" + beanContext.getContainer().getIdentifier() + beanContext.getId());
               /**
                * TODO:  Propagate created XPC as required (7.6.2.1 Inheritance of Extended Persistence Context
                *
                */

//               List <StatefulBeanContext> beanContexts = StatefulBeanContext.currentBean.getList();
//               for( StatefulBeanContext bc : beanContexts)
//               {
//                  bc.addExtendedPersistenceContext(kernelName, em);
//               }
            }
         }

         return em;
      }
      return null;
   }
}
{code}

{code}
public class ManagedEntityManagerFactoryHelper
{
   public static ManagedEntityManagerFactory getManagedEntityManagerFactory(String kernelName)
   {
      PersistenceUnitDeployment pu = (PersistenceUnitDeployment) PersistenceUnitRegistry.getPersistenceUnit(kernelName);
      if(pu != null)
         return pu.getManagedFactory();
      return null;
   }
}
{code}



--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira


More information about the jboss-jira mailing list