0

私はこれらに似ていると思う問題を抱えていますが、私のシナリオは少し異なります。

プロセスインスタンスをjBPM5で続行するにはどうすればよいですか?
http://community.jboss.org/message/600654

ヒューマンタスクAPI、ワークフローを進める方法は? http://community.jboss.org/message/614986#614986

これが私の問題です。以下を使用してプロセスを作成します。

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, transactionManager);

StatefulKnowledgeSession knowledgeSession = JPAKnowledgeService.newStatefulKnowledgeSession(knowledgeBase, null, env);
WorkItemHandler handler = new CommandBasedWSHumanTaskHandler(knowledgeSession);
knowledgeSession.getWorkItemManager().registerWorkItemHandler("Human Task", handler);

statefulSession.startProcess(processDefinitionId, processVariables);

statefulSession.dispose(); (Remember this line)

これは正常に機能します。プロセスが作成され、最初のヒューマンタスクが期待どおりに存在します。

次のステップは、タスククライアントを介してMina Task Clientを使用して、タスクを割り当てて完了することです。割り当ては完全に機能しますが、タスクを完了すると次の例外が発生します。

SEVERE: Could not commit session
java.lang.NullPointerException
    at org.drools.persistence.jpa.JpaPersistenceContextManager.beginCommandScopedEntityManager(JpaPersistenceContextManager.java:67)
    at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:287)
    at org.drools.command.impl.CommandBasedStatefulKnowledgeSession$1.completeWorkItem(CommandBasedStatefulKnowledgeSession.java:149)
    at org.jbpm.process.workitem.wsht.CommandBasedWSHumanTaskHandler$GetResultContentResponseHandler.execute(CommandBasedWSHumanTaskHandler.java:295)
    at org.jbpm.task.service.TaskClientHandler.messageReceived(TaskClientHandler.java:153)
    at org.jbpm.task.service.mina.MinaTaskClientHandler.messageReceived(MinaTaskClientHandler.java:47)
    at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:713)

これにより、タスクは完了しますが、次のタスクは作成されません。

この例外は、org.drools.persistence.jpa.JpaPersistenceContextManager.appScopedEntityManagerがnullであるためにスローされます。このフィールドは、JpaPersistenceContextManagerが作成されたときに初期化され、disposeメソッドが呼び出されたときにnullになります。

コメントアウトすることで、タスクを適切に完了することができました

// statefulSession.dispose();

良い解決策ではありません。セッションを永遠に開いたままにすることはできません。

問題の核心は、タスクを完了するときに、すでに破棄されているプロセスの作成に使用されたJpaPersistenceContextManagerを使用しようとすることです。

私の質問は、JpaPersistenceContextManagerを再初期化して、アクティブなentityManagerがあることを確認する方法を教えてください。Mina Task Clientを介して電話をかけているので、JpaPersistenceContextManagerに直接アクセスできないことを忘れないでください。

4

1 に答える 1

0

わかった。修正しました。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);
}


}

このバージョンは、有効なappScopedEntityManagerがあることを確認し、必要に応じて作成します。

次に、knowledgeSessionを作成するときに、JBPMによって提供されるデフォルトのものの代わりにこれが使用されていることを確認します。

        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);

これが他の人の役に立つことを願っています。

于 2011-09-05T11:09:29.533 に答える