[jboss-user] [jBPM] - Re: Completing a Task Fails after Calling statefulSession.dispose

James Williams do-not-reply at jboss.com
Fri Aug 19 22:54:19 EDT 2011


James Williams [http://community.jboss.org/people/williajd] created the discussion

"Re: Completing a Task Fails after Calling statefulSession.dispose"

To view the discussion, visit: http://community.jboss.org/message/621903#621903

--------------------------------------------------------------
OK. I've fixed it. I had to write my own version of the PersistenceContextManager.

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;


import org.drools.persistence.PersistenceContext;
import org.drools.persistence.jpa.JpaPersistenceContext;
import org.drools.runtime.Environment;
import org.drools.runtime.EnvironmentName;
import org.jbpm.persistence.JpaProcessPersistenceContext;
import org.jbpm.persistence.ProcessPersistenceContext;
import org.jbpm.persistence.ProcessPersistenceContextManager;


public class MultipleUseJpaPersistenceContextManager implements ProcessPersistenceContextManager {


    Environment env;
    private EntityManagerFactory emf;


    private EntityManager appScopedEntityManager;
    protected EntityManager cmdScopedEntityManager;


    private boolean internalAppScopedEntityManager;
    private boolean internalCmdScopedEntityManager;


    public MultipleUseJpaPersistenceContextManager(Environment env) {
        this.env = env;
        this.emf = (EntityManagerFactory) env.get(EnvironmentName.ENTITY_MANAGER_FACTORY);
    }


    public PersistenceContext getApplicationScopedPersistenceContext() {
*        checkAppScopedEntityManager();*
        return new JpaPersistenceContext(appScopedEntityManager);
    }


    private void checkAppScopedEntityManager() {
        if (this.appScopedEntityManager == null) {
            // Use the App scoped EntityManager if the user has provided it, and it is open.
            this.appScopedEntityManager = (EntityManager) this.env.get(EnvironmentName.APP_SCOPED_ENTITY_MANAGER);
            if (this.appScopedEntityManager != null && !this.appScopedEntityManager.isOpen()) {
                throw new RuntimeException("Provided APP_SCOPED_ENTITY_MANAGER is not open");
            }


            if (this.appScopedEntityManager == null) {
                internalAppScopedEntityManager = true;
                this.appScopedEntityManager = this.emf.createEntityManager();


                this.env.set(EnvironmentName.APP_SCOPED_ENTITY_MANAGER, this.appScopedEntityManager);
            } else {
                internalAppScopedEntityManager = false;
            }
        }
    }


    public PersistenceContext getCommandScopedPersistenceContext() {
        return new JpaPersistenceContext(this.cmdScopedEntityManager);
    }


    public void beginCommandScopedEntityManager() {
*        checkAppScopedEntityManager();*
        EntityManager cmdScopedEntityManager = (EntityManager) env.get(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER);
        if (cmdScopedEntityManager == null
                || (this.cmdScopedEntityManager != null && !this.cmdScopedEntityManager.isOpen())) {
            internalCmdScopedEntityManager = true;
            this.cmdScopedEntityManager = this.emf.createEntityManager(); // no need to call joinTransaction as it will
                                                                          // do so if one already exists
            this.env.set(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, this.cmdScopedEntityManager);
            cmdScopedEntityManager = this.cmdScopedEntityManager;
        } else {
            internalCmdScopedEntityManager = false;
        }
        cmdScopedEntityManager.joinTransaction();
        appScopedEntityManager.joinTransaction();
    }


    public void endCommandScopedEntityManager() {
        if (this.internalCmdScopedEntityManager) {
            this.env.set(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, null);
        }
    }


    public void dispose() {
        if (this.internalAppScopedEntityManager) {
            if (this.appScopedEntityManager != null && this.appScopedEntityManager.isOpen()) {
                this.appScopedEntityManager.close();
            }
            this.internalAppScopedEntityManager = false;
            this.env.set(EnvironmentName.APP_SCOPED_ENTITY_MANAGER, null);
            this.appScopedEntityManager = null;
        }


        if (this.internalCmdScopedEntityManager) {
            if (this.cmdScopedEntityManager != null && this.cmdScopedEntityManager.isOpen()) {
                this.cmdScopedEntityManager.close();
            }
            this.internalCmdScopedEntityManager = false;
            this.env.set(EnvironmentName.CMD_SCOPED_ENTITY_MANAGER, null);
            this.cmdScopedEntityManager = null;
        }
    }

    @Override
    public ProcessPersistenceContext getProcessPersistenceContext() {
        if (cmdScopedEntityManager == null) {
            this.emf.createEntityManager();;
        }
        return new JpaProcessPersistenceContext(cmdScopedEntityManager);
    }


}

This version checks that it has a valid appScopedEntityManager and creates one if necessary. 

I then make sure this one is used instead of the default one provided by JBPM when creating my knowledgeSession:

            Environment env = KnowledgeBaseFactory.newEnvironment();
            env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, entityManagerFactory);
            InitialContext ctx = new InitialContext();
            UserTransaction transactionManager = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
 *env.set(EnvironmentName.TRANSACTION_MANAGER,* 
*                    new JtaTransactionManager(transactionManager, null, transactionManager));*
*env.set(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER,* 
*                    new MultipleUseJpaPersistenceContextManager(env));*

            StatefulKnowledgeSession knowledgeSession = JPAKnowledgeService.newStatefulKnowledgeSession(knowledgeBase, null, env);

I hope this helps others.
--------------------------------------------------------------

Reply to this message by going to Community
[http://community.jboss.org/message/621903#621903]

Start a new discussion in jBPM at Community
[http://community.jboss.org/choose-container!input.jspa?contentType=1&containerType=14&container=2034]

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/jboss-user/attachments/20110819/3c317023/attachment-0001.html 


More information about the jboss-user mailing list