jbpm 子流程结束后 主流程token没有向下流转?
shanyuxiyun
2012-03-26
<p>首先我把一个包含子流程的流程实例跑完,然后有重新从主流程中某个节点回退到子流程中的某个节点,结果是子流程又一次执行到end(子流程token已经到达end),但是流程实例没有结束。而且必须手动结束主流程实例才能使主流程继续向下流转。为什么?</p><p>主流程定义文件(subprocess.xml):</p><p><br></p><pre name="code" class="xml"><process-definition
xmlns="" name="subprocess"> <start-state name="start1"> <transition name="" to="task1"></transition> </start-state> <task-node name="task1"> <task> <assignment class="com.lee.test.action.TaskHandler" /> </task> <transition name="" to="process_state"></transition> </task-node> <process-state name="process_state"> <sub-process name="subprocess_inner"></sub-process> <transition name="out" to="task2"></transition> </process-state> <task-node name="task2"> <transition name="" to="end1"></transition> <task> <assignment class="com.lee.test.action.TaskHandler" /> </task> <task> <assignment class="com.lee.test.action.TaskHandler" /> </task> </task-node> <end-state name="end1"></end-state> </process-definition></pre><p> 子流程定义文件(subprocess_inner.xml):</p><p><br></p><p></p><pre name="code" class="xml"><process-definition xmlns="" name="subprocess_inner"> <start-state name="start2"> <transition name="" to="task3"></transition> <event type="node-enter"> <action class = "com.lee.test.action.StateHandler" /> </event> </start-state> <task-node name="task3"> <transition name="" to="task4"></transition> <task name="sub-process-task11"> <assignment class="com.lee.test.action.TaskHandler" /> </task> </task-node> <task-node name="task4"> <transition name="" to="end2"></transition> <task name="sub-process-task21"> <assignment class="com.lee.test.action.TaskHandler" /> </task> <task name="sub-process-task22"> <assignment class="com.lee.test.action.TaskHandler" /> </task> </task-node> <end-state name="end2"></end-state> </process-definition></pre><p></p><p> 然后我把两个流程定义文件全部部署,并且走了一个完整的流程实例。</p><p>数据库中主流程实例id为1,子流程实例id为2.</p><p>下面是我的测试程序:</p><p></p><pre name="code" class="java">public void test2(){ //test() ; JbpmContext context = configuration.createJbpmContext() ; try { ProcessInstance subPi = context.loadProcessInstance(2); ProcessInstance pi = context.loadProcessInstance(1); Token token = pi.getRootToken() ; Token subToken = subPi.getRootToken() ; JbpmUtil.changeTokenState(context, token ,false ) ; JbpmUtil.changeTokenState(context, subToken , true ) ; subPi.setEnd(null) ; pi.setEnd(null) ; ProcessState ps = (ProcessState) pi.getProcessDefinition().getNode("process_state") ; Node tn = subPi.getProcessDefinition().getNode("task3") ; token.setTerminationImplicit(true) ; token.setSubProcessInstance(subPi) ; token.setNode(ps) ; token.setNodeEnter(new Date()) ; //subToken.setTerminationImplicit(true) ; subToken.setNodeEnter(new Date()) ; subToken.setNode(tn) ; subPi.setSuperProcessToken(token) ; tn.enter(new ExecutionContext(subToken)) ; assertEquals("task3", subPi.getRootToken().getNode().getName()) ; subPi.signal() ; assertEquals("task4", subPi.getRootToken().getNode().getName()) ; subPi.signal() ; assertEquals("end2", subPi.getRootToken().getNode().getName()) ; System.out.println("sub pi arrives in end and ended ? ->"+subPi.hasEnded()); // 必须手动结束 subPi.end() ; subToken.end() ; System.out.println("pi root node -> "+pi.getRootToken().getNode()); System.out.println("pi has ended ? -> "+pi.getRootToken().hasEnded()); System.out.println("pi end date - > "+pi.getEnd()); Transition tr = (Transition) pi.getRootToken().getAvailableTransitions().iterator().next(); System.out.println("pi next node ->"+tr.getTo().getName()); System.out.println("next transition -> "+tr.getName()); //pi.signal("out") ; assertEquals("task2", pi.getRootToken().getNode().getName()) ; System.out.println("pi cur node -> "+pi.getRootToken().getNode().getName()); pi.signal() ; assertEquals("end1", pi.getRootToken().getNode().getName()) ; //必须手动结束 pi.end() ; System.out.println("pi has ended ? ->"+pi.hasEnded()); System.out.println("sub pi has ended ? -> "+subPi.hasEnded()); System.out.println("token has ended ? -> "+token.hasEnded()); System.out.println("sub token has ended ? -> "+subToken.hasEnded()); } catch (Exception e) { context.setRollbackOnly() ; e.printStackTrace(); }finally{ context.close() ; } }</pre><p></p><p> 其中JbpmUtil类中的changeTokenState方法如下:</p><p></p><pre name="code" class="java">/** * * @param context * @param token * @param isAbleToReactivateParent * 设置token 为未结束状态 */ public static int changeTokenState(JbpmContext context , Token token , boolean isAbleToReactivateParent){ String sql = "update org.jbpm.graph.exe.Token t set t.end = ? , t.nodeEnter = ? , t.isAbleToReactivateParent = ? where t.id = ?" ; int rs = context.getSession().createQuery(sql) .setParameter(0, null ) .setParameter(1, null ) .setParameter(2, isAbleToReactivateParent) .setParameter(3, token.getId()) .setReadOnly(false) .executeUpdate() ; context.getSession().flush() ; System.out.println("token id : "+token.getId()+" token end set to => "+token.hasEnded()); return rs ; }</pre><p></p><p><br></p><p><br></p><p>上面程序中注释为 “必须手动结束” 的地方本来是自动处理的 为什么还需要手动处理?</p><p>望指教!</p> |