非法尝试将代理与两个开放会话(JBPM)相关联

时间:2018-01-23 12:36:04

标签: java hibernate jpa jbpm

我有一个使用JBPM(5.4)的应用程序。它执行多个应该在同一事务上运行的工作项操作。在每个操作中,它都会创建一个entityManager。 当我尝试运行其中一个进程时,我得到非法尝试将代理与两个打开的Sessions 异常相关联。

有没有办法在会话之间合并对象?我无法控制jbpm进程中的session / transaction。

此致

1 个答案:

答案 0 :(得分:0)

javax.transaction有同步接口,在这种情况下我认为你应该使用它。

此代码来自seam / Hibernate和jbpm之间的集成。

public class ManagedJbpmContext implements Synchronization
{
   private static final LogProvider log = Logging.getLogProvider(ManagedJbpmContext.class);

   private JbpmContext jbpmContext;
   private boolean synchronizationRegistered;

   @Create
   public void create() throws NamingException, RollbackException, SystemException
   {
      jbpmContext = Jbpm.instance().getJbpmConfiguration().createJbpmContext();
      assertNoTransactionManagement();
      log.debug( "created seam managed jBPM context");
   }

   private void assertNoTransactionManagement()
   {
      DbPersistenceServiceFactory dpsf = (DbPersistenceServiceFactory) jbpmContext.getJbpmConfiguration()
            .getServiceFactory(Services.SERVICENAME_PERSISTENCE);
      if ( dpsf.isTransactionEnabled() )
      {
         throw new IllegalStateException("jBPM transaction management is enabled, disable in jbpm.cfg.xml");
      }
   }

   @Unwrap
   public JbpmContext getJbpmContext() throws NamingException, RollbackException, SystemException
   {
      joinTransaction();
      return jbpmContext;
   }

   private void joinTransaction() throws SystemException
   {
      UserTransaction transaction = Transaction.instance();

      if ( !transaction.isActiveOrMarkedRollback() )
      {
         throw new IllegalStateException("JbpmContext may only be used inside a transaction");
      }

      if ( !synchronizationRegistered && !Lifecycle.isDestroying() && transaction.isActive() )
      {
         jbpmContext.getSession().isOpen();
         try //TODO: what we really want here is if (!cmt)
         {
            transaction.registerSynchronization(this);
         }
         catch (UnsupportedOperationException uoe)
         {
            jbpmContext.getSession().getTransaction().registerSynchronization(this);
         }
         synchronizationRegistered = true;
      }
   }

   public void beforeCompletion()
   {
      log.debug( "flushing seam managed jBPM context" );

      jbpmContext.getSession().flush();
      log.debug( "done flushing seam managed jBPM context" );
   }

   public void afterCompletion(int status) 
   {
      synchronizationRegistered = false;
      if ( !Contexts.isEventContextActive() )
      {
         //in calls to MDBs and remote calls to SBs, the 
         //transaction doesn't commit until after contexts
         //are destroyed, so wait until the transaction
         //completes before closing the session
         //on the other hand, if we still have an active
         //event context, leave it open
         closeContext();
      }
   }



   private void closeContext()
   {
      log.debug( "destroying seam managed jBPM context" );
      jbpmContext.close();
      log.debug( "done destroying seam managed jBPM context" );
   }

}