该帖已经被评为隐藏帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-11-27
经过一段事件的摸索终于将jpbm与spring完全整合,主要是事务处理的整合,工作流代码与业务代码在一个事务上下文进行; ========================================================
spring modules中包含了spring集成JBPM的机制,在使用的发现其并没有彻底解决两者的事务处理统一的问题,经过一段事件的摸索终于将jpbm与spring完全整合,主要是事务处理的整合,工作流代码与业务代码在一个事务上下文进行; 使用了springmodules的封装,对jbpm稍有修改,稍后附上解决办法及代码; -------------------------------------------------姗姗来吃---------------o(∩_∩)o...哈哈,害得帖子被隐藏了 第一步:首先引入spring-modules-jbpm31.jar,同时将jbpm包含的所有hibernate映射文件解压出来,集成到spring配置文件中,可以使用类路径下的目录形式简化,如下:
xml 代码
经测试在这种方式在weblogic上不能正常加载,从jar包加载也有问题必须解压到目录; xml 代码
xml 代码
第三步:配置spring modules,通过 springmodules 初始化jbpmConfiguration; xml 代码
<!-- jBPM configuration--> <bean id="jbpmConfiguration" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean"> <property name="sessionFactory" ref="sessionFactory" /> <property name="configuration" value="classpath:/conf/jbpm.cfg.xml" />注意这里 <!--<property name="configuration" value="classpath:/org/jbpm/default.jbpm.cfg.xml" />--> <!--<property name="processDefinitions">--> <!--<list>--> <!--<ref local="demoWorkflow" />--> <!--</list>--> <!--</property>--> <!--<property name="createSchema" value="true"/>--> </bean>
xml 代码(/conf/jbpm.cfg.xml) <jbpm-configuration> <jbpm-context> <!--<service name="persistence" factory="org.jbpm.persistence.db.DbPersistenceServiceFactory" />--> <service name="persistence"> <factory> <bean class="org.jbpm.persistence.db.DbPersistenceServiceFactory"> <field name="isTransactionEnabled"> <false /> 注意这里 </field> <field name="isCurrentSessionEnabled"> <true /> 注意这里 </field> </bean> </factory> </service> <service name="message" factory="org.jbpm.msg.db.DbMessageServiceFactory" /> <service name="scheduler" factory="org.jbpm.scheduler.db.DbSchedulerServiceFactory" /> <service name="logging" factory="org.jbpm.logging.db.DbLoggingServiceFactory" /> <service name="authentication" factory="org.jbpm.security.authentication.DefaultAuthenticationServiceFactory" /> </jbpm-context> <!--<string name="resource.hibernate.cfg.xml" value="hibernate.cfg.xml" />-->注意这里 <string name="resource.business.calendar" value="org/jbpm/calendar/jbpm.business.calendar.properties" /> <string name="resource.default.modules" value="org/jbpm/graph/def/jbpm.default.modules.properties" /> <string name="resource.converter" value="org/jbpm/db/hibernate/jbpm.converter.properties" /> <string name="resource.action.types" value="org/jbpm/graph/action/action.types.xml" /> <string name="resource.node.types" value="org/jbpm/graph/node/node.types.xml" /> <string name="resource.parsers" value="org/jbpm/jpdl/par/jbpm.parsers.xml" /> <string name="resource.varmapping" value="org/jbpm/context/exe/jbpm.varmapping.xml" /> <long name="jbpm.msg.wait.timout" value="5000" singleton="true" /> <int name="jbpm.byte.block.size" value="1024" singleton="true" /> <string name="mail.smtp.host" value="localhost" /> <bean name="jbpm.task.instance.factory" class="org.jbpm.taskmgmt.impl.DefaultTaskInstanceFactoryImpl" singleton="true" /> <bean name="jbpm.variable.resolver" class="org.jbpm.jpdl.el.impl.JbpmVariableResolver" singleton="true" /> <bean name="jbpm.mail.address.resolver" class="org.jbpm.identity.mail.IdentityAddressResolver" singleton="true" /> </jbpm-configuration>
第四步:修改JBPM自带的过滤器(web.xml),初始化当前请求线程的JBPM Context时从spring获取我们上面配置的jbpmConfiguration;其自带过滤器是通过JbpmConfiguration.getInstance获取的,不能公用spring事务上下文的hibernate session;
xml 代码
java 代码(JbpmContextHolder<!---->filter.java)
第六步:后话
由于JBPM本身的设计问题,采用这样的解决方案后对JBPM API的调用必须在事务环境中运行,例如不能直接在struts action调用JBPM API代码;当然有解决的办法,但是需要对JBPM做进一步的修改,小弟为了保持JBPM的纯洁性,只改了JBPM的外围代码,没有动大手术,o(∩_∩)o...
另一个相关的问题就是不能直接在单元测试中获取JBPMContext,需要手工开启事务管理器;
附单元测试代码:
public void testNonTrans() throws Exception { try { assertNull(jbpmConfiguration.getCurrentJbpmContext()); jbpmConfiguration.createJbpmContext(); JbpmContext context = jbpmConfiguration.getCurrentJbpmContext(); assertNotNull(context); System.out.println(help.getDecisionHandler());//有事务环境 try { help2.getProcessInstance(new Long(57424));//无事务环境:必然报错 // org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here assertTrue(false); } catch (Exception e) { assertTrue(true); } assertNotNull(basedao.getCurrentSession());//HibernateBaseDAO关联的hibernatetemplate默认的autocreate为true,所以可以得到session assertFalse(basedao.getCurrentSession() == basedao.getCurrentSession());//不在事务中每次创建新的不同的session assertTrue(context.getSessionFactory() == basedao.getSessionFactory());//SessionFactory公用 try { context.getSessionFactory().getCurrentSession();//无事务环境时从SessionFactory获取session必然报错,同context.getSession() // org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here assertTrue(false); } catch (Exception e) { assertTrue(true); } try { basedao.getSessionFactory().getCurrentSession();//无事务环境时从SessionFactory获取session必然报错 // org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here assertTrue(false); } catch (Exception e) { e.printStackTrace(); assertTrue(true); } assertNotNull(context.getSessionFactory().openSession()); assertNotNull(basedao.getSessionFactory().openSession()); assertFalse(context.getSessionFactory().openSession() == basedao.getSessionFactory().openSession()); assertTrue(true); } catch (Exception e) { e.printStackTrace(); assertFalse(true); //失败 } } public void testTransConfig() throws Exception { TransactionStatus status = beginTransation(); assertNull(jbpmConfiguration.getCurrentJbpmContext()); jbpmConfiguration.createJbpmContext(); JbpmContext context = jbpmConfiguration.getCurrentJbpmContext(); assertNotNull(context); try { System.out.println(help.getDecisionHandler()); System.out.println(help2.getProcessInstance(new Long(57424))); assertNotNull(context.getSession()); assertTrue(context.getSession() == context.getSession());//相同的session assertTrue(basedao.getCurrentSession() == basedao.getCurrentSession());//相同的session assertTrue(context.getSessionFactory() == basedao.getSessionFactory());//相同 assertTrue(context.getSession() == basedao.getCurrentSession());//相同 assertTrue(context.getSessionFactory().getCurrentSession() == basedao.getSessionFactory().getCurrentSession());//从相同的SessionFactory取getCurrentSession是相同的 } catch (Exception e) { e.printStackTrace(); } transactionManager.commit(status); /////////// }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-11-27
怎么都是稍后,广告?
|
|
返回顶楼 | |
发表时间:2008-01-03
请问:能否提供ApplicationContext类?
|
|
返回顶楼 | |
发表时间:2008-01-04
1。按照以上说明,目前不同的事,我的getJbpmConfiguration的写法如下,
protected JbpmConfiguration getJbpmConfiguration() { private static ApplicationContext ctx = null; public static void setCtx(ApplicationContext ctxa){ ctx=ctxa; } protected JbpmConfiguration getJbpmConfiguration() { if (ctx == null) { ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {"classpath*:spring/test-jbpm.xml"} ); setCtx(ctx); } JbpmConfiguration jc=(JbpmConfiguration)ctx.getBean("jbpmConfiguration"); return jc; } } 2。调用 通过struts action,调用service,具体如下写法: action:testSvc.testTran(busiEntity); 说明busiEntity,业务实体 service的testTran: 1)使用hiberate保存busiEntity 2)调用另外一个service,此service调用另外一个类A,类A扩展JbpmTemplate,实现保存jbpm的实例。 目前的差异问题,还是不能实现你说的业务和jbpm的事务保持一致的提交和回滚。 是否还有哪个地方不对? 能否将你的配置文件、调用方式在说说。 谢谢! |
|
返回顶楼 | |
浏览 7043 次