Shark的InstancePersistence是保存流程运行数据的主要模块。Shark的EventAudit保存了对流程运行数据的审计信息。这两部分改为Hibernate实现之后,可以在同一个事务中处理流程数据与业务数据,避免发生一些意外的错误——而这种错误往往是最令人头疼,最说不清楚的,特别是在系统的并发访问数量较大的时候。另外,改为Hibernate实现之后还有望提高系统性能。
Shark的源码中有Hibernate实现的代码,但是那是为shark的老版本服务的。在当前版本(1.1-2)中发生了很多变化,而Hibernate代码没有跟上:
- InstancePersistenceManager接口发生了一些变化,导致HibernateInstancePersistenceManager需要大量改动。这个类经完善之后,大约增加了2000行代码。
- 数据库有很大变化。每个表的主键都统一变为oid,随之而来的外键都发生了变化;增加了对Blob数据的两种处理方式,为此共增加了12张表
主键生成方式
通过HibernateUtilities类中的方法生成每个表的主键,用到了数据库表"counter"。在该表中,每个流程中用到的表都占一行,记录他们主键的最大值。HibernateUtilities类中为主键设置了Cache。
M/O映射
每个数据库表都有一个POJO与之对应。从Shark的角度来看,Shark提供了若干接口用于对持久化数据的管理,每个接口由一张或多张数据库表进行支持。因此要注意处理接口、数据库和POJO之间的关系。
大概是由于历史原因,Shark接口中的方法与数据库字段并不能一一对应,我采用的办法是在POJO中为一个属性提供两组getter、setter方法,一组实现接口,一组用于直接映射到数据库。直接映射到数据库的一组方法不是必须的,但是可以简化编程。这种办法实质上就是在POJO中实现数据转换。
对于EventAudit的4张表,由于有3张表有许多公共字段,在映射时我用了union-subclass进行简化处理,同时那3个POJO也继承自抽象的EventAudit类。
POJO类中,需要特别注意equals、toString和hashCode方法。如果是用meddle-gen 生成的,这3个方法只考虑了主键,而POJO还处于“transient”状态的时候由于还未分配主键无法通过主键进行比较,这样就会发生错误。因此,这3个方法中要加入更多的可识别本对象的字段
提升性能
InstancePersistence和EventAudit两项操作大量占用IO资源,可以考虑将这两项操作的数据分配到不同的存储设备