10个小时!被一个问题困扰!
问题描述:
用户执行一个任务的时候,JBPM没有把任务执行的结果持久化的数据库中。即没有任何的update或insert语句产生。而我所看的实例中,(实例没有spring),同样的代码却执行了持久化工作。通过观察流程的输出,已经可以看到成功的执行到了下一个流程节点,但是因为没有持久化,所以流程的信息没有被保存。
以下是java代码:
引用
jbpmTemplate.execute(new JbpmCallback(){
public Object doInJbpm(JbpmContext context) throws JbpmException {
TaskInstance instance = context.getTaskInstance(tid);
System.out.println("----------------"+instance.getName());
if("ok".equals(result))
{
instance.end();
}
if("no".equals(result))
{
instance.end("部门审批驳回");
}
return null;
}
});
因为使用了spring-jbpm-module,此处使用了它提供的jbpmTemplate
我开始跟踪源代码,在instance.end初设置断点。
TaskInstance类 执行end方法:核心代码:
if (transition==null) {
log.debug("completion of task '"+task.getName()+"' results in taking the default transition");
token.signal();
} else {
log.debug("completion of task '"+task.getName()+"' results in taking transition '"+transition+"'");
token.signal(transition);
}
然后进入Token类的signal方法
核心代码: node.leave(executionContext, transition);
进入Node类的leave方法:
核心代码:transition.take(executionContext);
进入Transition类的take方法:将执行环境传入方法中
核心代码:to.enter(executionContext);
再次进入Node类 这已经是下一个节点了。至此,已经完成了从一个节点进入另一个节点的过程调度。
没有发现任何的持久化代码!
究竟持久化代码在什么地方呐?
我突然想到,我使用的是JbpmTemplate类,调用它的doInJbpm方法,是一个回调方法,我于是又找到doInJbpm方法的源码:
public Object execute(final JbpmCallback callback) {
final JbpmContext context = getContext();
try {
// use the hibernateTemplate is present and if needed
if (hibernateTemplate != null && hasPersistenceService) {
// use hibernate template
return hibernateTemplate.execute(new HibernateCallback() {
/**
* @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
*/
public Object doInHibernate(Session session) throws HibernateException, SQLException {
// inject the session in the context
context.setSession(session);
return callback.doInJbpm(context);
}
});
}
// plain callback invocation (no template w/ persistence)
return callback.doInJbpm(context);
}
catch (JbpmException ex) {
throw convertJbpmException(ex);
}
finally {
releaseContext(context);
}
}
可以看到,它在执行完你实现的doInJbpm方法后在finally体中有个releaseContext方法,
从名字可以看出,该方法是释放jbpm上下文信息的。
看它的源码:
只有一句:jbpmContext.close();
再往里找:核心代码:
if (services!=null) {
try {
autoSave();
} finally {
services.close();
}
}
我看到了autoSave()方法。
我就开始找autoSave的源码:
if (autoSaveProcessInstances!=null) {
Iterator iter = autoSaveProcessInstances.iterator();
while (iter.hasNext()) {
ProcessInstance processInstance = (ProcessInstance) iter.next();
save(processInstance);
iter.remove();
}
}
我又执行了一次业务,发现执行到这儿的时候autoSaveProcessInstances是null,结果就没有执行下面的代码,整个执行也就结束了。
但是我在跟踪例子的时候发现它这儿的autoSaveProcessInstances也是null。
那是哪句呐?
又看了jbpmContext.close();源码:发现又有个finally块:
services.close();
继续找它的源码:
里面最核心的代码也只有一句: service.close();
service是个什么东东呐?是个接口,看它的实现:
通过断点跟踪,这儿的实现是:DbPersistenceService 这个也是我们在jbpm.cfg.xml中配置的。
看它对service.close的实现:
核心持久化代码:
Exception commitException = commit(); 这是在跟踪示例的时候发现是这一句完成的持久化工作。
从感觉上,似乎是异常后完成的事务提交...
而执行这一句的必要条件是:
if (! isRollbackOnly()) {....}
而我在跟踪我的代码的时候,发现这儿的if(...)内是false。。。这个isRollbackOnly是哪儿设置的呐?什么时候设置的 呐?我突然想起我对我的那个purchaseApplyService配置了spring的事务,于是我就去掉了事务配置。执行,结果还是一样。
我再次找了这个isRollbackOnly方法 。核心代码:return txService.isRollbackOnly();
这应该是个事务配置。但是在哪儿设置的rollbackOnly呐?我找到了TxService类。然后找到它的setRollbackOnly方法,使用eclipse找调用它的地方,发现:在JbpmContext类中有方法:
/**
* mark this transaction for rollback only in the persistence service.
* The {@link #close()} operation will then perform a rollback.
*/
public void setRollbackOnly() {
TxService txService = (services!=null ? services.getTxService() : null);
if (txService!=null) {
txService.setRollbackOnly();
} else {
throw new JbpmException("no transaction service configured");
}
}
于是我想,是不是我在使用springTemplate的方法时候,它给我提供的jbpmContext有问题呐?但是究竟是杂回事,我还是没有找到答案,但是找到个临时的解决办法,就是不使用jbpmContext,并且把JbpmConfiguration注入到我的PurchaseApplyFlowService类里。现在我的代码是:
JbpmContext jbpmContext=jbpmConfiguration.getCurrentJbpmContext();
if(jbpmContext==null)
{
jbpmContext=jbpmConfiguration.createJbpmContext();
}
TaskInstance ti=jbpmContext.getTaskInstance(Long.parseLong(taskId));
if("ok".equals(result))
{
ti.end();
}
if("no".equals(result))
{
ti.end("部门经理驳回");
}
jbpmContext.close();
执行,发现成功执行了持久化工作。。。
分享到:
相关推荐
因为有点大所以分了8份 一个自己学习到现在的结果吧,自己做的一个完整的借款流程应用,主要是用到了SPRING,在整合的过程中遇到过不少问题。我的博客有一些说明http://yuyanshan.javaeye.com/<br>
jbpm+spring的web简单借款工作流实例项目,里面含详细的数据库能运行
Jbpm+Spring+hibernate+struts2+mysql+c3p0项目部署
Struts+Hibernate+spring+jpa+lucene+jbpm+compass配置文件
jbpm+spring的web简单借款工作流实例项目.rar
因为有点大所以分了8份 一个自己学习到现在的结果吧,自己做的一个完整的借款流程应用,主要是用到了SPRING,在整合的过程中遇到过不少问题。我的博客有一些说明http://yuyanshan.javaeye.com/<br>
spring+jbpm的配置示例,jbpm配置,希望大家一起进行学习,共同提高
附带数据库,可以直接部署后运行。数据库版本为mysql
因为有点大所以分了8份 一个自己学习到现在的结果吧,自己做的一个完整的借款流程应用,主要是用到了SPRING,在整合的过程中遇到过不少问题。我的博客有一些说明http://yuyanshan.javaeye.com/<br>
因为有点大所以分了8份 一个自己学习到现在的结果吧,自己做的一个完整的借款流程应用,主要是用到了SPRING,在整合的过程中遇到过不少问题。我的博客有一些说明http://yuyanshan.javaeye.com/<br>
JBPM4.4+spring+ext整合
JBPM5+Spring+Hibernate+MySQL 请假例子
spring+struts+hibernate+jbpm+dwr整合开发的OA办公系统源码
jbpm4整合struts2+spring2.5+hibernate3.3.doc
因为有点大所以分了8份 一个自己学习到现在的结果吧,自己做的一个完整的借款流程应用,主要是用到了SPRING,在整合的过程中遇到过不少问题。我的博客有一些说明http://yuyanshan.javaeye.com/<br>
因为有点大所以分了8份 一个自己学习到现在的结果吧,自己做的一个完整的借款流程应用,主要是用到了SPRING,在整合的过程中遇到过不少问题。我的博客有一些说明http://yuyanshan.javaeye.com/<br>
下载后可用eclipse打开,直接部署在tomcat下跑,对初学者非常有用
Jbpm4.4+hibernate3.5.4+spring3.0.4+struts2.1.8整合 超级详细的文档,透彻讲解JBPM与SSH的整合过程