分类: 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,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.
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.
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.
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());
}
}