图6.1. 不同形态的转换
流程定义可以用三种不同的形式表现
ml, java objects 或jBPM数据库记录. 执行信息 (= 运行时间) 和日志信息可表现为2种形式 : java objects 和jBPM数据库记录.
有关XML表示流程定义和流程档案可以参看 第13章, jBPM 流程定义语言 (JPDL).
本章讨论java Object和jBPM数据库之间的转换.jBPM内部hibernate 保存java objects到数据库并且重现他们 . 当然不是严格限定使用jBPM必须有hibernate 的相关知识,这只是推荐使用hibernate.
更多的有关如何发布流程档案到数据库亲参看 13.1.1节, “发布流程档案”
6.1. 永久化API
图 6.2. The jBPM 数据库class
jBPM永久化操作可以根据名字类似 GraphSession, TaskMgmtSession 和 ContextSession等来找到 .从 JbpmSession可以获得命名的会话 . JbpmSession 可以从 JbpmSessionFactory获得.
JbpmSessionFactory 对你的应用程序来说是threadsafe保证的, 你需要一个 JbpmSessionFactory . 单件模式(Singleton)的延迟初始化(Lazy Initialization)(当心 issues延迟载入和double-check locking的问题 ).
在生成时间, JbpmSessionFactory预备了能让JbpmSession可以飞快建立的所有信息 .
作为一个用户, 你可以为每个thread或每个请求建立一个 JbpmSession . JbpmSession有一个JDBC connection 连接到数据库
JbpmSession 和 JbpmSessionFactory仅仅是包装它们的 hibernate副本. 高级的特性比如独立的数据For advanced features such as 脱管对象(detached objects)或乐观锁定, 参看hibernate文档.
public class PersistenceApiTest extends TestCase {
static JbpmSessionFactory jbpmSessionFactory = JbpmSessionFactory.buildJbpmSessionFactory();
public void testStartProcessInstance() {
// obtain a session
JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession();
try {
// start a user managed transaction
jbpmSession.beginTransaction();
// load information from the database
// (note that process definitions will be cached in memory
// in the second level cache of hibernate)
ProcessDefinition auctionProcess =
jbpmSession.getGraphSession().findLatestProcessDefinition("auction");
// perform a POJO workflow operation on the plain object model.
ProcessInstance auctionInstance = new ProcessInstance(auctionProcess);
auctionInstance.signal();
// store the result in the database
jbpmSession.getGraphSession().saveProcessInstance(auctionInstance);
// commit the user transaction
jbpmSession.commitTransaction();
} finally {
// close the session.
jbpmSession.close();
}
}
}
6.2. 数据库配置
最容易的配置the hibernate SessionFactory 的方式是把 hibernate.cfg.xml 放到根classpath里. hibernate.cfg.xml 包含了如何获得jdbc jdbc connections 和定位hibernate mapping 文件. 你可以在目录test/java发现比如mapping文件的例子.
更多关于配置hibernate的信息可以参看 hibernate 参考手册l, 配置章节.
6.3. 管理事务
jBPM 基本方式是平衡 hibernate 关于事务分界的能力. 这有两个最常见的场景来解释:
用户事务管理, JbpmSession 有方法
JbpmSession.beginTransaction()
JbpmSession.commitTransaction()
JbpmSession.rollbackTransaction()
这些方法的行为依赖hibernate的有关事务的配置.
如果你配置了hibernate 管理她自己的JDBC connections (比如 C3P0连接池), 那么事务操作的结果同JDBC connection一致. hibernate配置文件中(hibernate.cfg.xml) 配置要求你指明JDBC connection属性. 可选的, 你可以通过c3p0连接池的属性来配置连接池.
当你配置了hibernate 获得connection从应用服务器中的DataSource,那么事务的方法将同包容器中的UserTransaction object的方法保持一致.
更多有关配置事务的细节参看 hibernate 参考手册, 事务策略章节.
6.4. jBPM 数据库
jBPM 数据库包含流程定义,流程执行和日志数据. 流程定义数据是静态的不能改变(参看 章节13.1.2, “流程版本 . 流程执行是流程定义的参考数据. 流程日志包含了所有在流程执行中的变化信息.
6.4.1. Hibernate 整合
jBPM 使用 hibernate 3.0 作为它的 O/R映射. 这就意味着hibernate 有负责jBPM java object和这些对象在关系数据库中永久化对象的变换. 注意你开始使用jBPM不必了解Hibernate . Hibernate用于jBPM内部. 但是理解基本的hibernate, 会帮助你更好理解jBPM API的语义.
让我们看看一些例子和得到一些hibernate的功能了解:
发布流程档案 : 发布流程档案按照几个步骤, 在第一个步骤, 档案被解析并且相应的java object模型也被建立. 对象图将被hibernate处理. Hibernate将产生必要的相关SQL数据库插入语句 .
更新流程实例 : 另外一个功能是hibernate 脏数据检查功能. hibernate 在两个对象图中间计算不同并产生必要的对应数据库的update语句 (和插入及删除) 使java object和数据库保持一致. 因此当你想继续流程执行实例, 你使用 ProcessInstance JbpmSession.getGraphSession().loadProcessInstance(Long pid) , jBPM将委托这个调用到 hibernate. Hibernate将从数据库载入这个流程实例数据并且结构化成jBPM java objects. 在这之后,你可以自由的修改流程实例java objects就好象其他java objects一样.当你完成 (比如在在执行进入等待状态之后)后 你可以保存修改过的流程实例到数据库,通过调用 JbpmSession.getGraphSession().saveProcessInstance(ProcessInstance processInstance) . jBPM 同样委过这个任务到hibernate , hibernate 将计算给顶的processInstance和 原始从数据库中载入的processInstance .这叫做脏数据检查. Hibernate 会计算所有的不同并且产生必要的SQL语句来保证数据库和java object的同步.
执行这个任务, hibernate 需要一组mapping文件和配置文件. mapping 文件说明了java object 同数据库table之间的映射. jBPM 包括所有的jBPMdomain class的 mapping 文件.
hibernate配置文件中的主要信息是描述数据库连接的配置属性. 包括jdbc连接和数据库方言. SQL方言是重要的hibernate特性 : 数据库无关. 数据库每个类型一般说来都有同样的SQL, 但不同的数据库有稍微不同的SQL语法. Hibernate 知道这些区别并通过方言属性来建立正确的SQL. 可以参考hibernate文档查看支持的数据库清单.
6.4.2. 开发数据库是hsqldb
hypersonic数据库是理想的包含关系数据库的java软件的数据库. 尤其是 hypersonic in-memory 模型是非常便于编写包含数据操作的test unit . hypersonic in-memory 数据库保持所有的数据在内存中而不是保存在磁盘里. jBPM的单元测试将开始一个干净的空的in-memory数据库. 然后hibernate schema 生成工具将建立jBPM table. 我们提供的jBPM类mapping文件作为hibernate schema生成器的输入. 然后hibernate schema 生成器根据信息生成数据库schema (DDL)脚本. 这些DDL 语句将在hypersonic in-memory数据库上执行用来建立新的,空的jBPM 数据库.
6.4.3. 其他数据库支持
为了支持除了hypersonic in-memory 数据库而提供了jbpm 数据库扩展包: jbpm-<version>-db.zip . 参看 章节2.1, “可下载一览” . 这个包报案ant 脚本来测试jBPM是否为支持的不同的数据库产生数据库的DDL脚本 (create, drop和clean)
在展开 jbpm-<version>-db.zip , 更新 build.properties并且设置 jbpm.3.location 到安装jbpm的主目录(相对路径或绝对路径)
数据包扩展包包括一个ant建造script (build.xml ) 在根目录下. 这个脚本包括建立jBPM支持的数据库生成脚本和测试脚本.运行 ant -p 得到关于建造目标更多的信息. readme.html文件介绍了更多的有关不同数据库实现的信息及状态.
生成的脚本是默认的脚本.如果想为特定的使用定制或优化 , 你必须询问你的DBA 先查看数据库脚本. 通常的定制是额外的索引或增加text字段的最大值.
如果你的数据库不被支持,你可以用我们介绍的方法在你的数据库上来测试jBPM . 我们希望支持所有的数据库,所以可以把你的数据库的下列信息让我们知道.:
jbpm.test.hibernate.properties 配置文件
那里可以下载数据库驱动和数据库版本
你碰到的任何问题