jbpm 子流程结束后 主流程token没有向下流转?

shanyuxiyun 2012-03-26
<p>首先我把一个包含子流程的流程实例跑完,然后有重新从主流程中某个节点回退到子流程中的某个节点,结果是子流程又一次执行到end(子流程token已经到达end),但是流程实例没有结束。而且必须手动结束主流程实例才能使主流程继续向下流转。为什么?</p><p>主流程定义文件(subprocess.xml):</p><p><br></p><pre name="code" class="xml">&lt;process-definition
  xmlns=""  name="subprocess"&gt;
   &lt;start-state name="start1"&gt;
      &lt;transition name="" to="task1"&gt;&lt;/transition&gt;
   &lt;/start-state&gt;
   &lt;task-node name="task1"&gt;
       &lt;task&gt;
      &lt;assignment class="com.lee.test.action.TaskHandler" /&gt;
      &lt;/task&gt;
      &lt;transition name="" to="process_state"&gt;&lt;/transition&gt;
   &lt;/task-node&gt;
   &lt;process-state name="process_state"&gt;
   &lt;sub-process name="subprocess_inner"&gt;&lt;/sub-process&gt;
      &lt;transition name="out" to="task2"&gt;&lt;/transition&gt;
   &lt;/process-state&gt;
   &lt;task-node name="task2"&gt;
      &lt;transition name="" to="end1"&gt;&lt;/transition&gt;
       &lt;task&gt;
      &lt;assignment class="com.lee.test.action.TaskHandler" /&gt;
      &lt;/task&gt;
       &lt;task&gt;
      &lt;assignment class="com.lee.test.action.TaskHandler" /&gt;
      &lt;/task&gt;
   &lt;/task-node&gt;
   &lt;end-state name="end1"&gt;&lt;/end-state&gt;
&lt;/process-definition&gt;</pre><p>&nbsp;子流程定义文件(subprocess_inner.xml):</p><p><br></p><p></p><pre name="code" class="xml">&lt;process-definition
  xmlns=""  name="subprocess_inner"&gt;
   &lt;start-state name="start2"&gt;
      &lt;transition name="" to="task3"&gt;&lt;/transition&gt;
       &lt;event type="node-enter"&gt;
    &lt;action class = "com.lee.test.action.StateHandler" /&gt;
      &lt;/event&gt;
   &lt;/start-state&gt;
   &lt;task-node name="task3"&gt;
      &lt;transition name="" to="task4"&gt;&lt;/transition&gt;
       &lt;task name="sub-process-task11"&gt;
      &lt;assignment class="com.lee.test.action.TaskHandler" /&gt;
      &lt;/task&gt;
   &lt;/task-node&gt;
   &lt;task-node name="task4"&gt;
      &lt;transition name="" to="end2"&gt;&lt;/transition&gt;
       &lt;task  name="sub-process-task21"&gt;
      &lt;assignment class="com.lee.test.action.TaskHandler" /&gt;
      &lt;/task&gt;
       &lt;task  name="sub-process-task22"&gt;
      &lt;assignment class="com.lee.test.action.TaskHandler" /&gt;
      &lt;/task&gt;
   &lt;/task-node&gt;
   &lt;end-state name="end2"&gt;&lt;/end-state&gt;
&lt;/process-definition&gt;</pre><p></p><p>&nbsp;然后我把两个流程定义文件全部部署,并且走了一个完整的流程实例。</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 ? -&gt;"+subPi.hasEnded());

// 必须手动结束
subPi.end() ;
subToken.end() ;

System.out.println("pi root node -&gt; "+pi.getRootToken().getNode());
System.out.println("pi has ended ? -&gt; "+pi.getRootToken().hasEnded());
System.out.println("pi end date - &gt; "+pi.getEnd());


Transition tr = (Transition) pi.getRootToken().getAvailableTransitions().iterator().next();
System.out.println("pi next node -&gt;"+tr.getTo().getName());
System.out.println("next transition -&gt; "+tr.getName());
//pi.signal("out") ;


assertEquals("task2", pi.getRootToken().getNode().getName()) ;


System.out.println("pi cur node -&gt; "+pi.getRootToken().getNode().getName());
pi.signal() ;
assertEquals("end1", pi.getRootToken().getNode().getName()) ;

//必须手动结束
pi.end() ;


System.out.println("pi has ended ? -&gt;"+pi.hasEnded());
System.out.println("sub pi has ended ? -&gt; "+subPi.hasEnded());

System.out.println("token has ended ? -&gt; "+token.hasEnded());
System.out.println("sub token has ended ? -&gt; "+subToken.hasEnded());

} catch (Exception e) {
context.setRollbackOnly() ;
e.printStackTrace();
}finally{
context.close() ;
}
}</pre><p></p><p>&nbsp;其中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 =&gt; "+token.hasEnded());
return    rs ;

}</pre><p></p><p><br></p><p><br></p><p>上面程序中注释为 &nbsp;“必须手动结束” &nbsp;的地方本来是自动处理的 &nbsp;为什么还需要手动处理?</p><p>望指教!</p>
Global site tag (gtag.js) - Google Analytics