JBPM撤回功能中清除历史痕迹的方法
(本文针对 的是JBPM4.4)
JBPM进行撤回操作的实现方式,大体上的步骤就是:
1.在transition或task的事件处理器EventListener中动态创建路径
2.当用户在前台执行撤回操作时,后台在service中执行流程推回
3.清除历史记录。
现在的关键就在于第三步,清除历史记录上。
难点就是JBPM没有提供清除历史记录这一功能的API(人家老外压根就没想这一块)。
怎么办呢,JBPM也是建立在hibernate之上的。
网络上可以得到几种方法:
A方法:
EnvironmentImpl.getCurrent().get(DbSession.class)
B方法:
EnvironmentImpl environment = ((EnvironmentFactory) processEngine).openEnvironment(); //获取JBPM的环境
DbSession session = environment.get(DbSession.class);
经试验,在Service中直接使用A方法, EnvironmentImpl.getCurrent()得到的是NULL,不可行。
B方法,经试验成功,成功使用得到的session执行了删除操作:
HistoryService hs = processEngine.getHistoryService();
List<HistoryActivityInstance> hinsts = hs
.createHistoryActivityInstanceQuery().executionId(execid)
.activityName(actiName)
.orderDesc(HistoryActivityInstanceQuery.PROPERTY_ENDTIME)
.list();
if (hinsts == null || hinsts.size() == 0) {
throw new AppException("清除历史记录时发生异常,历史不存在!");
}
HistoryActivityInstance toDel=hinsts.get(0);
EnvironmentImpl environment = ((EnvironmentFactory) processEngine).openEnvironment(); //获取JBPM的环境
DbSession session = environment.get(DbSession.class);
session.delete(toDel);
但是接下来进行其它处理时,报出了“org.hibernate.SessionException: Session is closed!”的异常,具体原来不太清楚,但很明显,jbpm或hibernate受到了影响,应用系统崩溃啦 !
回想起JBPM4.4工作流应用开发指南上所写的,才明白为什么Command模式在JBPM中那么重要。
这样就好了,将以上代码放在Command中处理。
尽管你在Spring中对Service会开启事务,JBPM也会使用Spring开启的事务,从而保证事务一致、异常回滚,但使用Command还是有明显的好处的。
看一看Command接口,你会惊喜的发现它的execute(Enviroment enviroment )方法传入了一个Enviroment 的实例,我们可以方便地得到session对象:
Session session=enviroment.get(Session.class);
不用绞尽脑汁地去获取session对象了吧,呵呵!
我还没试,如果不行,还会续...