2013-04-11 45 views
0

環境:JBPM 5 - RESOURCE_LOCAL持久

jbpm的v5.4.0.Final, 口水5.5.0.Final, 彈簧v3.0.6.RELEASE, 甲骨文, 休眠EM v4.0.0.Final, JPA v2

我已將Web應用程序配置爲使用帶有RESOURCE_LOCAL事務的JBPM。

我現在面臨3個問題:

1)workiteminfo是沒有得到持續

2)JPAWorkingMemoryDbLogger的日誌不獲取持久化到數據庫表。

3)當人工任務完成時,即使在任務完成後調用Session.getWorkItemManager().completeWorkItem,會話也不會執行實例中的其他節點。因此,新任務不會創建。

我已將persistence.xml配置爲使用「RESOURCE_LOCAL」事務。 我已將DroolsSpringJPAManager配置爲非JTA。

我應該在創建環境會話時明確創建命令範圍的EntityManager?

+0

更新:我從頭開始。我用d-泉爲我建立了完整的會議。我正在使用RESOURCE_LOCAL持久性。現在工作正常。 – 2013-04-22 04:04:35

回答

0

這裏的和jBPM 5.4.0.Final一個例子:

package com.sample; 

import java.util.List; 

import javax.persistence.EntityManagerFactory; 

import org.drools.KnowledgeBase; 
import org.drools.SystemEventListenerFactory; 
import org.drools.container.spring.beans.persistence.DroolsSpringJpaManager; 
import org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager; 
import org.drools.impl.EnvironmentFactory; 
import org.drools.persistence.PersistenceContextManager; 
import org.drools.persistence.TransactionManager; 
import org.drools.persistence.jpa.JPAKnowledgeService; 
import org.drools.runtime.Environment; 
import org.drools.runtime.EnvironmentName; 
import org.drools.runtime.StatefulKnowledgeSession; 
import org.drools.runtime.process.ProcessInstance; 
import org.jbpm.process.audit.JPAProcessInstanceDbLog; 
import org.jbpm.process.audit.JPAWorkingMemoryDbLogger; 
import org.jbpm.process.audit.ProcessInstanceLog; 
import org.jbpm.process.workitem.wsht.SyncWSHumanTaskHandler; 
import org.jbpm.task.TaskService; 
import org.jbpm.task.identity.UserGroupCallback; 
import org.jbpm.task.identity.UserGroupCallbackManager; 
import org.jbpm.task.query.TaskSummary; 
import org.jbpm.task.service.local.LocalTaskService; 
import org.jbpm.task.service.persistence.TaskSessionSpringFactoryImpl; 
import org.jbpm.test.JBPMHelper; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 
import org.springframework.transaction.TransactionStatus; 
import org.springframework.transaction.support.AbstractPlatformTransactionManager; 
import org.springframework.transaction.support.DefaultTransactionDefinition; 

/** 
* This is a sample file to launch a process. 
*/ 
public class TestSpringLocalEMF { 

    public static final void main(String[] args) throws Throwable { 
     JBPMHelper.startH2Server(); 

     UserGroupCallbackManager.getInstance().setCallback(new UserGroupCallback() { 
      public boolean existsGroup(String arg0) { 
       return true; 
      } 
      public boolean existsUser(String arg0) { 
       return true; 
      } 
      public List<String> getGroupsForUser(String arg0, 
        List<String> arg1, List<String> arg2) { 
       return arg2; 
      } 
     }); 

     ClassPathXmlApplicationContext context = 
      new ClassPathXmlApplicationContext("spring-conf.xml"); 

     EntityManagerFactory emf = (EntityManagerFactory) context.getBean("jbpmEMF"); 

     Environment env = EnvironmentFactory.newEnvironment(); 
     env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);  

     AbstractPlatformTransactionManager aptm = (AbstractPlatformTransactionManager) context.getBean("jbpmTxManager");  
     TransactionManager transactionManager = new DroolsSpringTransactionManager(aptm); 
     env.set(EnvironmentName.TRANSACTION_MANAGER, transactionManager); 

     PersistenceContextManager persistenceContextManager = new DroolsSpringJpaManager(env); 
     env.set(EnvironmentName.PERSISTENCE_CONTEXT_MANAGER, persistenceContextManager); 

     KnowledgeBase kbase = (KnowledgeBase) context.getBean("kbase"); 
     StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession(kbase, null, env); 
     new JPAWorkingMemoryDbLogger(ksession); 

     org.jbpm.task.service.TaskService internalTaskService = new org.jbpm.task.service.TaskService(); 
     internalTaskService.setSystemEventListener(SystemEventListenerFactory.getSystemEventListener()); 
     TaskSessionSpringFactoryImpl springFactory = new TaskSessionSpringFactoryImpl(); 
     springFactory.setEntityManagerFactory(emf);  
     springFactory.setTaskService(internalTaskService); 
     springFactory.setTransactionManager(transactionManager); 
     springFactory.setUseJTA(true); 
     springFactory.initialize(); 
     TaskService taskService = new LocalTaskService(internalTaskService); 

     SyncWSHumanTaskHandler humanTaskHandler = new SyncWSHumanTaskHandler(taskService, ksession); 
     humanTaskHandler.setLocal(true); 
     humanTaskHandler.connect(); 
     ksession.getWorkItemManager().registerWorkItemHandler("Human Task", humanTaskHandler); 

     ProcessInstance processInstance = ksession.startProcess("com.sample.bpmn.hello"); 

     System.out.println("Process started"); 

     List<TaskSummary> tasks = taskService.getTasksAssignedAsPotentialOwner("john", "en-UK"); 
     System.out.println("Found " + tasks.size() + " task(s) for user 'john'"); 
     if (tasks.size() != 1) { 
      throw new IllegalArgumentException("Incorrect amount of tasks"); 
     } 
     long taskId = tasks.get(0).getId(); 
     taskService.start(taskId, "john"); 
     taskService.complete(taskId, "john", null); 

     tasks = taskService.getTasksAssignedAsPotentialOwner("mary", "en-UK"); 
     System.out.println("Found " + tasks.size() + " task(s) for user 'mary'"); 
     if (tasks.size() != 1) { 
      throw new IllegalArgumentException("Incorrect amount of tasks"); 
     } 
     taskId = tasks.get(0).getId(); 
     taskService.start(taskId, "mary"); 
     taskService.complete(taskId, "mary", null); 

     processInstance = ksession.getProcessInstance(processInstance.getId()); 
     if (processInstance == null) { 
      System.out.println("Process instance completed"); 
     } 

     System.out.println("******************************************************************"); 

     DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 
     TransactionStatus status = aptm.getTransaction(def); 

     processInstance = ksession.startProcess("com.sample.bpmn.hello"); 
     long processInstanceId = processInstance.getId(); 

     aptm.rollback(status); 

     processInstance = ksession.getProcessInstance(processInstanceId); 

     if (processInstance == null) { 
      System.out.println("Process instance rolled back"); 
     } else { 
      throw new IllegalArgumentException("Process instance not rolled back"); 
     } 

     tasks = taskService.getTasksAssignedAsPotentialOwner("john", "en-UK"); 
     System.out.println("Found " + tasks.size() + " task(s) for user 'john'"); 
     if (tasks.size() != 0) { 
      throw new IllegalArgumentException("Incorrect amount of tasks"); 
     } 

     JPAProcessInstanceDbLog.setEnvironment(env); 
     ProcessInstanceLog log = JPAProcessInstanceDbLog.findProcessInstance(processInstanceId); 
     if (log != null) { 
      throw new IllegalArgumentException("Log not rolled back"); 
     } 

     System.exit(0); 
    } 

} 

用的persistence.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<persistence version="1.0" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
           http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd 
           http://java.sun.com/xml/ns/persistence/orm 
           http://java.sun.com/xml/ns/persistence/orm_1_0.xsd" 
      xmlns:orm="http://java.sun.com/xml/ns/persistence/orm" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns="http://java.sun.com/xml/ns/persistence"> 

    <persistence-unit name="org.jbpm.persistence.jpa.local" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <jta-data-source>jdbc/jbpm-ds</jta-data-source> 

    <mapping-file>META-INF/JBPMorm.xml</mapping-file> 
    <mapping-file>META-INF/ProcessInstanceInfo.hbm.xml</mapping-file> 
    <mapping-file>META-INF/Taskorm.xml</mapping-file> 

    <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class> 
    <class>org.drools.persistence.info.SessionInfo</class> 
    <class>org.drools.persistence.info.WorkItemInfo</class> 
    <class>org.drools.persistence.info.SessionInfo</class> 
    <class>org.drools.persistence.info.WorkItemInfo</class> 

    <class>org.jbpm.process.audit.ProcessInstanceLog</class> 
    <class>org.jbpm.process.audit.NodeInstanceLog</class> 
    <class>org.jbpm.process.audit.VariableInstanceLog</class> 

    <class>org.jbpm.task.Attachment</class> 
    <class>org.jbpm.task.Content</class> 
    <class>org.jbpm.task.BooleanExpression</class> 
    <class>org.jbpm.task.Comment</class> 
    <class>org.jbpm.task.Deadline</class> 
    <class>org.jbpm.task.Comment</class> 
    <class>org.jbpm.task.Deadline</class> 
    <class>org.jbpm.task.Delegation</class> 
    <class>org.jbpm.task.Escalation</class> 
    <class>org.jbpm.task.Group</class> 
    <class>org.jbpm.task.I18NText</class> 
    <class>org.jbpm.task.Notification</class> 
    <class>org.jbpm.task.EmailNotification</class> 
    <class>org.jbpm.task.EmailNotificationHeader</class> 
    <class>org.jbpm.task.PeopleAssignments</class> 
    <class>org.jbpm.task.Reassignment</class> 
    <class>org.jbpm.task.Status</class> 
    <class>org.jbpm.task.Task</class> 
    <class>org.jbpm.task.TaskData</class> 
    <class>org.jbpm.task.SubTasksStrategy</class> 
    <class>org.jbpm.task.OnParentAbortAllSubTasksEndStrategy</class> 
    <class>org.jbpm.task.OnAllSubTasksEndParentEndStrategy</class> 
    <class>org.jbpm.task.User</class> 

    <properties> 
     <property name="hibernate.max_fetch_depth" value="3"/> 
     <property name="hibernate.hbm2ddl.auto" value="create" /> 
     <property name="hibernate.show_sql" value="true" /> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/> 
    </properties> 

    </persistence-unit> 

</persistence> 

和彈簧conf.xml中

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:jbpm="http://drools.org/schema/drools-spring"  
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
          http://drools.org/schema/drools-spring org/drools/container/spring/drools-spring-1.5.0.xsd"> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="org.h2.Driver"/> 
    <property name="url" value="jdbc:h2:tcp://localhost/~/jbpm-db"/> 
    <property name="username" value="sa"/> 
    <property name="password" value=""/> 
    </bean> 

    <bean id="jbpmEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="persistenceUnitName" value="org.jbpm.persistence.jpa.local"/> 
    </bean> 

    <bean id="jbpmTxManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="jbpmEMF"/> 
    <property name="nestedTransactionAllowed" value="false"/> 
    </bean> 

    <jbpm:kbase id="kbase"> 
    <jbpm:resources> 
     <jbpm:resource type="BPMN2" source="classpath:sample.bpmn"/> 
    </jbpm:resources> 
    </jbpm:kbase> 

</beans> 

和sample.bpmn

<?xml version="1.0" encoding="UTF-8"?> 
<definitions id="Definition" 
      targetNamespace="http://www.jboss.org/drools" 
      typeLanguage="http://www.java.com/javaTypes" 
      expressionLanguage="http://www.mvel.org/2.0" 
      xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd" 
      xmlns:g="http://www.jboss.org/drools/flow/gpd" 
      xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" 
      xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" 
      xmlns:di="http://www.omg.org/spec/DD/20100524/DI" 
      xmlns:tns="http://www.jboss.org/drools"> 

    <process processType="Private" isExecutable="true" id="com.sample.bpmn.hello" name="Hello World" > 

    <!-- nodes --> 
    <startEvent id="_1" name="Start" /> 
    <endEvent id="_3" name="End" > 
     <terminateEventDefinition/> 
    </endEvent> 
    <userTask id="_4" name="Task 1" > 
     <ioSpecification> 
     <dataInput id="_4_CommentInput" name="Comment" /> 
     <dataInput id="_4_SkippableInput" name="Skippable" /> 
     <dataInput id="_4_TaskNameInput" name="TaskName" /> 
     <dataInput id="_4_ContentInput" name="Content" /> 
     <dataInput id="_4_GroupIdInput" name="GroupId" /> 
     <dataInput id="_4_PriorityInput" name="Priority" /> 
     <inputSet> 
      <dataInputRefs>_4_CommentInput</dataInputRefs> 
      <dataInputRefs>_4_SkippableInput</dataInputRefs> 
      <dataInputRefs>_4_TaskNameInput</dataInputRefs> 
      <dataInputRefs>_4_ContentInput</dataInputRefs> 
      <dataInputRefs>_4_GroupIdInput</dataInputRefs> 
      <dataInputRefs>_4_PriorityInput</dataInputRefs> 
     </inputSet> 
     <outputSet> 
     </outputSet> 
     </ioSpecification> 
     <dataInputAssociation> 
     <targetRef>_4_CommentInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression"></from> 
      <to xsi:type="tFormalExpression">_4_CommentInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_4_SkippableInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression">false</from> 
      <to xsi:type="tFormalExpression">_4_SkippableInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_4_TaskNameInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression">Task1</from> 
      <to xsi:type="tFormalExpression">_4_TaskNameInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_4_ContentInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression"></from> 
      <to xsi:type="tFormalExpression">_4_ContentInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_4_GroupIdInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression"></from> 
      <to xsi:type="tFormalExpression">_4_GroupIdInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_4_PriorityInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression"></from> 
      <to xsi:type="tFormalExpression">_4_PriorityInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <potentialOwner> 
     <resourceAssignmentExpression> 
      <formalExpression>john</formalExpression> 
     </resourceAssignmentExpression> 
     </potentialOwner> 
    </userTask> 
    <userTask id="_5" name="Task 2" > 
     <ioSpecification> 
     <dataInput id="_5_CommentInput" name="Comment" /> 
     <dataInput id="_5_SkippableInput" name="Skippable" /> 
     <dataInput id="_5_TaskNameInput" name="TaskName" /> 
     <dataInput id="_5_ContentInput" name="Content" /> 
     <dataInput id="_5_GroupIdInput" name="GroupId" /> 
     <dataInput id="_5_PriorityInput" name="Priority" /> 
     <inputSet> 
      <dataInputRefs>_5_CommentInput</dataInputRefs> 
      <dataInputRefs>_5_SkippableInput</dataInputRefs> 
      <dataInputRefs>_5_TaskNameInput</dataInputRefs> 
      <dataInputRefs>_5_ContentInput</dataInputRefs> 
      <dataInputRefs>_5_GroupIdInput</dataInputRefs> 
      <dataInputRefs>_5_PriorityInput</dataInputRefs> 
     </inputSet> 
     <outputSet> 
     </outputSet> 
     </ioSpecification> 
     <dataInputAssociation> 
     <targetRef>_5_CommentInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression"></from> 
      <to xsi:type="tFormalExpression">_5_CommentInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_5_SkippableInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression">false</from> 
      <to xsi:type="tFormalExpression">_5_SkippableInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_5_TaskNameInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression">Task2</from> 
      <to xsi:type="tFormalExpression">_5_TaskNameInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_5_ContentInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression"></from> 
      <to xsi:type="tFormalExpression">_5_ContentInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_5_GroupIdInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression"></from> 
      <to xsi:type="tFormalExpression">_5_GroupIdInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <dataInputAssociation> 
     <targetRef>_5_PriorityInput</targetRef> 
     <assignment> 
      <from xsi:type="tFormalExpression"></from> 
      <to xsi:type="tFormalExpression">_5_PriorityInput</to> 
     </assignment> 
     </dataInputAssociation> 
     <potentialOwner> 
     <resourceAssignmentExpression> 
      <formalExpression>mary</formalExpression> 
     </resourceAssignmentExpression> 
     </potentialOwner> 
    </userTask> 

    <!-- connections --> 
    <sequenceFlow id="_5-_3" sourceRef="_5" targetRef="_3" /> 
    <sequenceFlow id="_1-_4" sourceRef="_1" targetRef="_4" /> 
    <sequenceFlow id="_4-_5" sourceRef="_4" targetRef="_5" /> 

    </process> 

    <bpmndi:BPMNDiagram> 
    <bpmndi:BPMNPlane bpmnElement="com.sample.bpmn.hello" > 
     <bpmndi:BPMNShape bpmnElement="_1" > 
     <dc:Bounds x="16" y="16" width="48" height="48" /> 
     </bpmndi:BPMNShape> 
     <bpmndi:BPMNShape bpmnElement="_3" > 
     <dc:Bounds x="360" y="16" width="48" height="48" /> 
     </bpmndi:BPMNShape> 
     <bpmndi:BPMNShape bpmnElement="_4" > 
     <dc:Bounds x="96" y="16" width="100" height="48" /> 
     </bpmndi:BPMNShape> 
     <bpmndi:BPMNShape bpmnElement="_5" > 
     <dc:Bounds x="228" y="16" width="100" height="48" /> 
     </bpmndi:BPMNShape> 
     <bpmndi:BPMNEdge bpmnElement="_5-_3" > 
     <di:waypoint x="278" y="40" /> 
     <di:waypoint x="384" y="40" /> 
     </bpmndi:BPMNEdge> 
     <bpmndi:BPMNEdge bpmnElement="_1-_4" > 
     <di:waypoint x="40" y="40" /> 
     <di:waypoint x="146" y="40" /> 
     </bpmndi:BPMNEdge> 
     <bpmndi:BPMNEdge bpmnElement="_4-_5" > 
     <di:waypoint x="146" y="40" /> 
     <di:waypoint x="278" y="40" /> 
     </bpmndi:BPMNEdge> 
    </bpmndi:BPMNPlane> 
    </bpmndi:BPMNDiagram> 

</definitions> 
+0

謝謝你克里斯。我在persistence.xml中使用了non-jta-datasource來實現RESOURCE_LOCAL持久性,但是您已經使用了jta-datasource。我認爲它應該沒問題。 – 2013-04-22 04:07:26