Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1002513
  • 博文数量: 152
  • 博客积分: 4937
  • 博客等级: 上校
  • 技术积分: 1662
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-05 16:55
文章分类

全部博文(152)

文章存档

2013年(12)

2012年(6)

2011年(58)

2010年(43)

2009年(1)

2008年(15)

2007年(17)

我的朋友

分类: Java

2008-06-29 18:04:45

6.5 部署processdefinition.xml

    我们要把 processdefinition.xml 的流程定义的数据部署到数据库中,因为 jBPM 在正式运行的时候不是去读 processdefinition.xml 文件,而是去读数据库中的流程定义。    这里写了一个个 JUnit 程序来部署 processdefinition.xml ,当然你用普通的 Java Main 也可以。

package com.sample;

 

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.InputStream;

 

import junit.framework.TestCase;

 

import org.jbpm.JbpmConfiguration;

import org.jbpm.JbpmContext;

import org.jbpm.graph.def.ProcessDefinition;

 

/**

 * 部署 processdefinition.xml

  *

 * @author chengang

  *

  */

public class DeployProcessTest extends TestCase {

    /**

     * 在本方法执行完毕后,检查 jbpm_processdefinition 表会多了一条记录

      *

     * @throws FileNotFoundException

      */

    public void testDeployProcessDefinition() throws FileNotFoundException {

       // jbpm.cfg.xml 取得 jbpm 的配置

       JbpmConfiguration config = JbpmConfiguration.getInstance();

       // 创建一个 jbpm 容器

       JbpmContext jbpmContext = config.createJbpmContext();

       // processdefinition.xml 生成相对应的流程定义类 ProcessDefinition

       InputStream is = new FileInputStream("processes/simple/processdefinition.xml");

       ProcessDefinition processDefinition = ProcessDefinition.parseXmlInputStream(is);

       // 利用容器的方法将流程定义数据部署到数据库上

       jbpmContext.deployProcessDefinition(processDefinition);

       // 关闭 jbpmContext

       jbpmContext.close();

    }

 

}

 

运行此程序,在控制台打印了一些日志,通过。如果出错,仔佃阅读出错信息以判断错误原因,并确定你按照前面两节:“修改 hibernate.cfg.xml ”和“完善库引用”的内容做好了设置。

 (如果抛出异常09:32:43,791 [main] ERROR ErrorCounter : *** ERROR: line 3:45: expecting "set", found 't'
09:32:43,822 [main] ERROR ErrorCounter : *** ERROR: line 3:45: expecting "set", found 't'
09:32:43,869 [main] ERROR ErrorCounter : *** ERROR: line 3:50: unexpected token: t
09:32:43,931 [main] ERROR SessionFactoryImpl : Error in named query: SchedulerSession.deleteTimersForProcessInstance
org.hibernate.hql.ast.QuerySyntaxError: unexpected token: t near line 3, column 50 [
     
        delete from org.jbpm.scheduler.exe.Timer t
        where t.processInstance = :processInstance
     
    ]
 at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:63)
 at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:215)
 at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:127)
 at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:83)
 at org.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:427)
 at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:388)
 at org.hibernate.impl.SessionFactoryImpl.(SessionFactoryImpl.java:291)
 at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1005)
 at org.jbpm.persistence.db.DbPersistenceServiceFactory.getSessionFactory(DbPersistenceServiceFactory.java:93)
 at org.jbpm.persistence.db.DbPersistenceService.getSessionFactory(DbPersistenceService.java:74)
 at org.jbpm.persistence.db.DbPersistenceService.getSession(DbPersistenceService.java:78)
 at org.jbpm.persistence.db.DbPersistenceService.getGraphSession(DbPersistenceService.java:201)
 at org.jbpm.JbpmContext.getGraphSession(JbpmContext.java:427)
 at org.jbpm.JbpmContext.deployProcessDefinition(JbpmContext.java:166)
 at com.hanxr.jbpm.action.DeployProcessTest.testDeployProcessDefinition(DeployProcessTest.java:35)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:324)
 at junit.framework.TestCase.runTest(TestCase.java:154)
 at junit.framework.TestCase.runBare(TestCase.java:127)
 at junit.framework.TestResult$1.protect(TestResult.java:106)
 at junit.framework.TestResult.runProtected(TestResult.java:124)
 at junit.framework.TestResult.run(TestResult.java:109)
 at junit.framework.TestCase.run(TestCase.java:118)
 at junit.framework.TestSuite.runTest(TestSuite.java:208)
 at junit.framework.TestSuite.run(TestSuite.java:203)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: line 3:50: unexpected token: t
 at org.hibernate.hql.antlr.HqlBaseParser.deleteStatement(HqlBaseParser.java:242)
 at org.hibernate.hql.antlr.HqlBaseParser.statement(HqlBaseParser.java:139)
 at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:209)
 ... 28 more
09:32:43,947 [main] ERROR SessionFactoryImpl : Error in named query: SchedulerSession.suspendTimersForToken
org.hibernate.hql.ast.QuerySyntaxError: expecting "set", found 't' near line 3, column 45 [
     
        update org.jbpm.scheduler.exe.Timer t
        set t.isSuspended = true
        where t.token = :token
     
    ]
 at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:63)
 at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:215)
 at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:127)
 at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:83)
 at org.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:427)
 at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:388)
 at org.hibernate.impl.SessionFactoryImpl.(SessionFactoryImpl.java:291)
 at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1005)
 at org.jbpm.persistence.db.DbPersistenceServiceFactory.getSessionFactory(DbPersistenceServiceFactory.java:93)
 at org.jbpm.persistence.db.DbPersistenceService.getSessionFactory(DbPersistenceService.java:74)
 at org.jbpm.persistence.db.DbPersistenceService.getSession(DbPersistenceService.java:78)
 at org.jbpm.persistence.db.DbPersistenceService.getGraphSession(DbPersistenceService.java:201)
 at org.jbpm.JbpmContext.getGraphSession(JbpmContext.java:427)
 at org.jbpm.JbpmContext.deployProcessDefinition(JbpmContext.java:166)
 at com.hanxr.jbpm.action.DeployProcessTest.testDeployProcessDefinition(DeployProcessTest.java:35)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:324)
 at junit.framework.TestCase.runTest(TestCase.java:154)
 at junit.framework.TestCase.runBare(TestCase.java:127)
 at junit.framework.TestResult$1.protect(TestResult.java:106)
 at junit.framework.TestResult.runProtected(TestResult.java:124)
 at junit.framework.TestResult.run(TestResult.java:109)
 at junit.framework.TestCase.run(TestCase.java:118)
 at junit.framework.TestSuite.runTest(TestSuite.java:208)
 at junit.framework.TestSuite.run(TestSuite.java:203)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: line 3:45: expecting "set", found 't'
 at antlr.Parser.match(Parser.java:211)
 at org.hibernate.hql.antlr.HqlBaseParser.setClause(HqlBaseParser.java:337)
 at org.hibernate.hql.antlr.HqlBaseParser.updateStatement(HqlBaseParser.java:183)
 at org.hibernate.hql.antlr.HqlBaseParser.statement(HqlBaseParser.java:133)
 at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:209)
 ... 28 more
09:32:43,947 [main] ERROR SessionFactoryImpl : Error in named query: SchedulerSession.resumeTimersForToken
org.hibernate.hql.ast.QuerySyntaxError: expecting "set", found 't' near line 3, column 45 [
     
        update org.jbpm.scheduler.exe.Timer t
        set t.isSuspended = false
        where t.token = :token
     
    ]
 at org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:63)
 at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:215)
 at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:127)
 at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:83)
 at org.hibernate.impl.SessionFactoryImpl.getQuery(SessionFactoryImpl.java:427)
 at org.hibernate.impl.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:388)
 at org.hibernate.impl.SessionFactoryImpl.(SessionFactoryImpl.java:291)
 at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1005)
 at org.jbpm.persistence.db.DbPersistenceServiceFactory.getSessionFactory(DbPersistenceServiceFactory.java:93)
 at org.jbpm.persistence.db.DbPersistenceService.getSessionFactory(DbPersistenceService.java:74)
 at org.jbpm.persistence.db.DbPersistenceService.getSession(DbPersistenceService.java:78)
 at org.jbpm.persistence.db.DbPersistenceService.getGraphSession(DbPersistenceService.java:201)
 at org.jbpm.JbpmContext.getGraphSession(JbpmContext.java:427)
 at org.jbpm.JbpmContext.deployProcessDefinition(JbpmContext.java:166)
 at com.hanxr.jbpm.action.DeployProcessTest.testDeployProcessDefinition(DeployProcessTest.java:35)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:324)
 at junit.framework.TestCase.runTest(TestCase.java:154)
 at junit.framework.TestCase.runBare(TestCase.java:127)
 at junit.framework.TestResult$1.protect(TestResult.java:106)
 at junit.framework.TestResult.runProtected(TestResult.java:124)
 at junit.framework.TestResult.run(TestResult.java:109)
 at junit.framework.TestCase.run(TestCase.java:118)
 at junit.framework.TestSuite.runTest(TestSuite.java:208)
 at junit.framework.TestSuite.run(TestSuite.java:203)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: line 3:45: expecting "set", found 't'
 at antlr.Parser.match(Parser.java:211)
 at org.hibernate.hql.antlr.HqlBaseParser.setClause(HqlBaseParser.java:337)
 at org.hibernate.hql.antlr.HqlBaseParser.updateStatement(HqlBaseParser.java:183)
 at org.hibernate.hql.antlr.HqlBaseParser.statement(HqlBaseParser.java:133)
 at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:209)
 ... 28 more
则修改JBossIDE-1.5.1.GA-ALL\eclipse\plugins\org.jbpm.core_3.0.8.1\build\jbpm-3.1-beta3.jar\org\jbpm\db\hibernate.queries.hbm.xml文件

 
              delete from org.jbpm.scheduler.exe.Timer t
        where t.processInstance = :processInstance
      ]]>
   

   
              update org.jbpm.scheduler.exe.Timer t
        set t.isSuspended = true
        where t.token = :token
      ]]>
   

   
              update org.jbpm.scheduler.exe.Timer t
        set t.isSuspended = false
        where t.token = :token
      ]]>
   

改为:
 
              delete from org.jbpm.scheduler.exe.Timer
        where processInstance = :processInstance
      ]]>
   

   
              update org.jbpm.scheduler.exe.Timer
        set isSuspended = true
        where token = :token
      ]]>
   

   
              update org.jbpm.scheduler.exe.Timer
        set isSuspended = false
        where token = :token
      ]]>
   

)

6.6 从数据库中的查看部署效果

无论是 MySQL 还是 Oracle ,查询 jbpm_processdefinition 表,你会发现多了一条记录,如下图 ( PLSQL Developer 的显示为例 )

依次检查各表我们可以发现有如下变化:




并由此简单判断出各表的作用,表中各字段的作用由字段名也能知晓一二。

jbpm_processdefinition

一个流程定义文件对应一条记录,可记录多个流程定义文件,可记录一个流程定义文件的对个版本。

jbpm_action

记录 ActionHandler 的对象实例(以名称为标识)

jbpm_delegation

记录了 ActionHandler 全类名,以便于用反射方式来加载

jbpm_envent

它的 transition 引用了 Jbpm_transition 表的 id ,再看其它字段,估计此表是表示流程转向事件的一个实例,或者是一个各表之间的联接表。

jbpm_node

流程结点

jbpm_transition

流程的转向定义

jbpm_variableaccess

流程中携带的变量。 ACCESS 字段是这些变量的读写权限

 

jBPM 的客户端开发

有了前面的 HelloWorld 后台流程,我们就要开始客户端程序了。正如前面提到的,本文不写 JSP ,而改采用 JUnit 的形式,输出则用 System.out.println 。举一反三,知道在方法中输入及用 println 输出,在 JSP SWING GUI 界面还不是一样嘛。

 

这个 JUnit 客户端,我们就借用创建项目时自动生成的 SimpleProcessTest.java 了,改写后如下:

package com.sample;

 

import junit.framework.TestCase;

 

import org.jbpm.JbpmConfiguration;

import org.jbpm.JbpmContext;

import org.jbpm.context.exe.ContextInstance;

import org.jbpm.graph.def.ProcessDefinition;

import org.jbpm.graph.exe.ProcessInstance;

 

public class SimpleProcessTest extends TestCase {

 

    private JbpmConfiguration config = JbpmConfiguration.getInstance();

    private JbpmContext ctx = config.createJbpmContext();

    // helloworld 对应于 jbpm_processdefinition 表的 name 字段值,也即 processdefinition.xml name

    // 这个值得取比较耗时,实际项目里最好和“数据库的 JDBC 连接”一样,让它共享,不要频繁打开关闭。

    private ProcessDefinition processDefinition = ctx.getGraphSession().findLatestProcessDefinition("helloworld");

 

    public void testNewRequest() {

       long id = newRequest();

       System.out.println("id=" + id);

       checkNewRequest(id);

       confirmRequest(id);

       checkconfirmRequest(id);

       ctx.close();// 关闭 jbpm 容器

    }

 

    /**

      * 创建一个请假单

      *

      * @return

      */

    private long newRequest() {

       // 创建一个新流程

       ProcessInstance pi = processDefinition.createProcessInstance();

       // 取得流程的数据环境

       ContextInstance ci = pi.getContextInstance();

       // 创建一张请假单

       ci.setVariable("name", " 陈刚 " );

       ci.setVariable("day", 2);

       assertEquals(null, ci.getVariable("note"));

       // 请假申请结束,转到下一个流程结点

       pi.signal();

       return pi.getId();

    }

 

    /**

      * 检查请假单的数据

      *

      * @param id

      */

    private void checkNewRequest(long id) {

       // 从数据库提取原流程

       ProcessInstance pi = ctx.loadProcessInstance(id);

       // 取得流程的数据环境

       ContextInstance ci = pi.getContextInstance();

       // 创建一张请假单

       assertEquals(" 陈刚 " , ci.getVariable("name"));

       assertEquals(Integer.valueOf(2), ci.getVariable("day"));

       assertEquals(" 我要请假 " , ci.getVariable("note"));

 

       // 当前是结点为 confirm

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

       // 流程还没结束

       assertFalse(pi.hasEnded());

    }

 

    /**

      * 审批陈刚的请假申请

      *

      * @param id

      */

    private void confirmRequest(long id) {

       ProcessInstance pi = ctx.loadProcessInstance(id);

       ContextInstance ci = pi.getContextInstance();

       // 不通过

       ci.setVariable("note", " 不准请假,继续加班 " );

       // 审批结束,到下一个流程结点

       pi.signal();

    }

 

    private void checkConfirmRequest(long id) {

       ProcessInstance pi = ctx.loadProcessInstance(id);

       ContextInstance ci = pi.getContextInstance();

       // ConfirmAction 类在 signal 后执行,所以覆盖了经理的审批意见

       assertEquals(" 准假 " , ci.getVariable("note"));

 

       // 当前是结点为 end

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

       // 流程结束了

       assertTrue(pi.hasEnded());

    }

 

}

阅读(2536) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~