jbpm4 整合SSH2 兼容 hibernate4
2014-10-16 10:40
393 查看
废话不多说,jbpm4默认支持hibernate3.
整合过程如下:
研究过JBPM的人都知道,JBPM在操作流程时,一切都是基于ProcessEngine对象,所以整合的思路很简单,只要我们能让Spring创建出ProcessEngine,整合就算是迈出一大步,我们先在spring配置文件applicationContext-common.xml中添加如下:
在这里创建processEngine 对象,在这里用到jbpm.cfg.xml
文件内容如下:
看到这里,或许你又会问:jbpm.cfg.xml里又引用了那么多的文件,这些文件在哪里?这些文件,你不用担心,他们都在jbpm.jar文件里,这不是我们管的事。
到这里,算完了吗?还没有!前面说过,JBPM要数据库表的支持才能工作,JBPM又是使用Hibernate操作数据库,就不免要配置Hibernate的表与实体的映射文件,如下:
我本地是这样配置的也可以,我的hibernate配置信息也一并交给spring管理,所以在applicationContext-common.xml文件中
这个标签内增加如下内容:
这里说个题外话:
言归正传,
下面一步,就是jar包的添加,如果你已经整合了SSH2,那么你只需要再添加jbpm.jar, juel-api.jar,juel-engine.jar,juel-impl.jar,mail.jar即可。
这里需要注意:
juel-api.jar,juel-engine.jar,juel-impl.jar
这三个jar有可能会导致jar冲突,我本人的环境tomcat6.0 中存在这个问题,
解决办法:
把这三个jar包直接放到tomcat6.0/lib 下边,程序中就不要添加了,然后删除tomcat 6.0 原来的el-api.jar
如果是hinernate3的话到此就结束了。
问题是hibernate4怎么处理:
经过查资料总结如下经验:
jbpm4.4默认用的是hibernate3,如果要使用hibernate4整合,则要覆写一些类,一共3个,如图:
注意,你可以直接在项目中建如上几个包,然后创建这三个类,下面介绍这三个类的内容,你如果想看原内容,自行查询源码,在你下载的jbpm4.4中有,这里就不多说了。
(1)BlobStrategyBlob.java
从上面可以看出,我就修改了一行,即15行换作16行内容:
SpringContextUtil是我本地的一个工具类,其目的就是根据在spring注册的bean名称获取实例,上面16行代码换成以下四行:
(2)SpringProcessEngine.java
这个文件,其实就是把35行代码:
替换为
(3)HibernateSessionDescriptor.java
这个文件是把78行换做79行。
到此基本就完成了,大部分 都应该成功了。如果不成功,有可能是连接池使用问题,因为我本人也遇到该问题
我的数据源配置如下:
因为我用的是tomcat 6.0 所以代码中这两种方式,估计都会有问题。
解决办法:
替换tomcat中的tomcat-dbcp.jar文件。
我用tomcat7.0中的tomcat-dbcp.jar 替换完就可以了。
写的不好,希望能帮助到你。
整合过程如下:
研究过JBPM的人都知道,JBPM在操作流程时,一切都是基于ProcessEngine对象,所以整合的思路很简单,只要我们能让Spring创建出ProcessEngine,整合就算是迈出一大步,我们先在spring配置文件applicationContext-common.xml中添加如下:
<!-- jbpm配置 --> <!-- 默认配置 这样需要jbpm.cfg.xml在classes目录下--> <bean id="springHelper" class="org.jbpm.pvm.internal.processengine.SpringHelper" /> <!-- 配置 这样可以自行胚子jbpm.cfg.xml所在位置--> <!-- <bean id="springHelper" class="org.jbpm.pvm.internal.processengine.SpringHelper"> <property name="jbpmCfg" value="jbpm.cfg.xml" /> </bean> --> <bean id="processEngine" factory-bean="springHelper" factory-method="createProcessEngine" /> <!-- 模板配置自己写的,不是必须的 --> <bean id="jbpmTemplate" class="cn.seven.jbpm.util.JbpmTemplate"> <property name="processEngine" ref="processEngine"></property> <property name="baseHiber" ref="baseHiber"></property> </bean>
在这里创建processEngine 对象,在这里用到jbpm.cfg.xml
文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <jbpm-configuration> <import resource="jbpm.default.cfg.xml" /> <import resource="jbpm.businesscalendar.cfg.xml" /> <!-- <import resource="jbpm.tx.hibernate.cfg.xml" /> --> <import resource="jbpm.tx.spring.cfg.xml" /> <import resource="jbpm.jpdl.cfg.xml" /> <import resource="jbpm.bpmn.cfg.xml" /> <import resource="jbpm.identity.cfg.xml" /> <import resource="jbpm.console.cfg.xml" /> <!-- Job executor is excluded for running the example test cases. --> <!-- To enable timers and messages in production use, this should be included. --> <!-- <import resource="jbpm.jobexecutor.cfg.xml" /> --> <!-- <import resource="jbpm.mail.templates.examples.xml" /> --> <process-engine-context> <string name="spring.cfg" value="classpath:/config/applicationContext-common.xml" /> </process-engine-context> </jbpm-configuration>
看到这里,或许你又会问:jbpm.cfg.xml里又引用了那么多的文件,这些文件在哪里?这些文件,你不用担心,他们都在jbpm.jar文件里,这不是我们管的事。
到这里,算完了吗?还没有!前面说过,JBPM要数据库表的支持才能工作,JBPM又是使用Hibernate操作数据库,就不免要配置Hibernate的表与实体的映射文件,如下:
<property name="mappingLocations"> <list> <value>classpath:jbpm.execution.hbm.xml</value> <value>classpath:jbpm.history.hbm.xml</value> <value>classpath:jbpm.identity.hbm.xml</value> <value>classpath:jbpm.repository.hbm.xml</value> <value>classpath:jbpm.task.hbm.xml</value> </list> </property>
我本地是这样配置的也可以,我的hibernate配置信息也一并交给spring管理,所以在applicationContext-common.xml文件中
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> </bean>
这个标签内增加如下内容:
<!-- 如果使用配置文件 --> <property name="mappingResources"> <list> <value>jbpm.repository.hbm.xml</value> <value>jbpm.execution.hbm.xml</value> <value>jbpm.history.hbm.xml</value> <value>jbpm.task.hbm.xml</value> <value>jbpm.identity.hbm.xml</value> </list> </property>
这里说个题外话:
mappingResources、mappingLocations、mappingDirectoryLocations、mappingJarLocations 他们的区别: 1. mappingResources:指定classpath下具体映射文件名 <property name="mappingResources"> <value>petclinic.hbm.xml </value> </property> 2. mappingLocations:可以指定任何文件路径,并且可以指定前缀:classpath、file等 <property name="mappingLocations"> <value>/WEB-INF/petclinic.hbm.xml </value> </property> <property name="mappingLocations"> <value>classpath:/com/company/domain/petclinic.hbm.xml </value> </property> 也可以用通配符指定,'*'指定一个文件(路径)名,'**'指定多个文件(路径)名,例如: <property name="mappingLocations"> <value>classpath:/com/company/domainmaps/*.hbm.xml </value> </property> 上面的配置是在com/company/domain包下任何maps路径下的hbm.xml文件都被加载为映射文件 3. mappingDirectoryLocations:指定映射的文件路径 <property name="mappingDirectoryLocations"> <list> <value>WEB-INF/HibernateMappings</value> </list> </property> 也可以通过classpath来指出 <property name="mappingDirectoryLocations"> <list> <value>classpath:/XXX/package/</value> </list> </property>
言归正传,
下面一步,就是jar包的添加,如果你已经整合了SSH2,那么你只需要再添加jbpm.jar, juel-api.jar,juel-engine.jar,juel-impl.jar,mail.jar即可。
这里需要注意:
juel-api.jar,juel-engine.jar,juel-impl.jar
这三个jar有可能会导致jar冲突,我本人的环境tomcat6.0 中存在这个问题,
解决办法:
把这三个jar包直接放到tomcat6.0/lib 下边,程序中就不要添加了,然后删除tomcat 6.0 原来的el-api.jar
如果是hinernate3的话到此就结束了。
问题是hibernate4怎么处理:
经过查资料总结如下经验:
jbpm4.4默认用的是hibernate3,如果要使用hibernate4整合,则要覆写一些类,一共3个,如图:
注意,你可以直接在项目中建如上几个包,然后创建这三个类,下面介绍这三个类的内容,你如果想看原内容,自行查询源码,在你下载的jbpm4.4中有,这里就不多说了。
(1)BlobStrategyBlob.java
package org.jbpm.pvm.internal.lob; import java.sql.SQLException; import org.hibernate.SessionFactory; import org.jbpm.api.JbpmException; import cn.seven.framework.spring.util.SpringContextUtil; public class BlobStrategyBlob implements BlobStrategy { public void set(byte[] bytes, Lob lob) { if (bytes!=null) { lob.cachedBytes = bytes; //lob.blob = Hibernate.createBlob(bytes); --源码(hinernate3)--seven lob.blob = ((SessionFactory)SpringContextUtil.getBean("sessionFactory")).getCurrentSession().getLobHelper().createBlob(bytes); } } public byte[] get(Lob lob) { if (lob.cachedBytes!=null) { return lob.cachedBytes; } java.sql.Blob sqlBlob = lob.blob; if (sqlBlob!=null) { try { return sqlBlob.getBytes(1, (int) sqlBlob.length()); } catch (SQLException e) { throw new JbpmException("couldn't extract bytes out of blob", e); } } return null; } }
从上面可以看出,我就修改了一行,即15行换作16行内容:
SpringContextUtil是我本地的一个工具类,其目的就是根据在spring注册的bean名称获取实例,上面16行代码换成以下四行:
ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(ServletActionContext.getServletContext()); SessionFactory sessionFactory = (SessionFactory)ac.getBean("sessionFactory"); Session session = sessionFactory.getCurrentSession(); lob.blob = session.getLobHelper().createBlob(bytes);
(2)SpringProcessEngine.java
/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jbpm.pvm.internal.processengine; import org.hibernate.cfg.Configuration; import org.jbpm.api.ProcessEngine; import org.jbpm.internal.log.Log; import org.jbpm.pvm.internal.cfg.ConfigurationImpl; import org.jbpm.pvm.internal.env.EnvironmentFactory; import org.jbpm.pvm.internal.env.EnvironmentImpl; import org.jbpm.pvm.internal.env.PvmEnvironment; import org.jbpm.pvm.internal.env.SpringContext; import org.jbpm.pvm.internal.wire.descriptor.ProvidedObjectDescriptor; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.orm.hibernate4.LocalSessionFactoryBean; /** * this environment factory will see only the singleton beans. * * The created {@link SpringEnvironment}s will see the prototype beans and it * will cache them. * * @author Andries Inze */ public class SpringProcessEngine extends ProcessEngineImpl implements EnvironmentFactory, ProcessEngine { private static final Log log = Log.getLog(SpringProcessEngine.class.getName()); private static final long serialVersionUID = 1L; private ApplicationContext applicationContext; public static ProcessEngine create(ConfigurationImpl configuration) { SpringProcessEngine springProcessEngine = null; ApplicationContext applicationContext = null; if (configuration.isInstantiatedFromSpring()) { applicationContext = (ApplicationContext) configuration.getApplicationContext(); springProcessEngine = new SpringProcessEngine(); springProcessEngine.applicationContext = applicationContext; springProcessEngine.initializeProcessEngine(configuration); LocalSessionFactoryBean localSessionFactoryBean = springProcessEngine.get(LocalSessionFactoryBean.class); Configuration hibernateConfiguration = localSessionFactoryBean.getConfiguration(); springProcessEngine.processEngineWireContext .getWireDefinition() .addDescriptor(new ProvidedObjectDescriptor(hibernateConfiguration, true)); springProcessEngine.checkDb(configuration); } else { String springCfg = (String) configuration.getProcessEngineWireContext().get("spring.cfg"); if (springCfg==null) { springCfg = "applicationContext.xml"; } applicationContext = new ClassPathXmlApplicationContext(springCfg); springProcessEngine = (SpringProcessEngine) applicationContext.getBean("processEngine"); } return springProcessEngine; } public EnvironmentImpl openEnvironment() { PvmEnvironment environment = new PvmEnvironment(this); if (log.isTraceEnabled()) log.trace("opening jbpm-spring" + environment); environment.setContext(new SpringContext(applicationContext)); installAuthenticatedUserId(environment); installProcessEngineContext(environment); installTransactionContext(environment); return environment; } @SuppressWarnings("unchecked") @Override public <T> T get(Class<T> type) { String[] names = applicationContext.getBeanNamesForType(type); if (names.length >= 1) { if (names.length > 1 && log.isWarnEnabled()) { log.warn("Multiple beans for type " + type + " found. Returning the first result."); } return (T) applicationContext.getBean(names[0]); } return super.get(type); } @Override public Object get(String key) { if (applicationContext.containsBean(key)) { return applicationContext.getBean(key); } return super.get(key); } }
这个文件,其实就是把35行代码:
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
替换为
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
(3)HibernateSessionDescriptor.java
/* * JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jbpm.pvm.internal.wire.descriptor; import java.sql.Connection; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.internal.SessionImpl; import org.jbpm.internal.log.Log; import org.jbpm.pvm.internal.env.EnvironmentImpl; import org.jbpm.pvm.internal.tx.HibernateSessionResource; import org.jbpm.pvm.internal.tx.StandardTransaction; import org.jbpm.pvm.internal.wire.WireContext; import org.jbpm.pvm.internal.wire.WireDefinition; import org.jbpm.pvm.internal.wire.WireException; /** * @author Tom Baeyens */ public class HibernateSessionDescriptor extends AbstractDescriptor { private static final long serialVersionUID = 1L; private static final Log log = Log.getLog(HibernateSessionDescriptor.class.getName()); protected String factoryName; protected boolean useCurrent = false; protected boolean tx = true; protected boolean close = true; protected String standardTransactionName; protected String connectionName; public Object construct(WireContext wireContext) { EnvironmentImpl environment = EnvironmentImpl.getCurrent(); if (environment==null) { throw new WireException("no environment"); } // get the hibernate-session-factory SessionFactory sessionFactory = null; if (factoryName!=null) { sessionFactory = (SessionFactory) wireContext.get(factoryName); } else { sessionFactory = environment.get(SessionFactory.class); } if (sessionFactory==null) { throw new WireException("couldn't find hibernate-session-factory "+(factoryName!=null ? "'"+factoryName+"'" : "by type ")+"to open a hibernate-session"); } // open the hibernate-session Session session = null; if (useCurrent) { if (log.isTraceEnabled()) log.trace("getting current hibernate session"); session = sessionFactory.getCurrentSession(); } else if (connectionName!=null) { Connection connection = (Connection) wireContext.get(connectionName); if (log.isTraceEnabled()) log.trace("creating hibernate session with connection "+connection); //session = sessionFactory.openSession(connection);源码内容-seven- session = (Session) sessionFactory.openStatelessSession(connection); } else { if (log.isTraceEnabled()) log.trace("creating hibernate session"); session = sessionFactory.openSession(); } StandardTransaction standardTransaction = environment.get(StandardTransaction.class); if (standardTransaction!=null) { HibernateSessionResource hibernateSessionResource = new HibernateSessionResource(session); standardTransaction.enlistResource(hibernateSessionResource); } return session; } public Class<?> getType(WireDefinition wireDefinition) { return SessionImpl.class; } public void setFactoryName(String factoryName) { this.factoryName = factoryName; } public void setTx(boolean tx) { this.tx = tx; } public void setStandardTransactionName(String standardTransactionName) { this.standardTransactionName = standardTransactionName; } public void setConnectionName(String connectionName) { this.connectionName = connectionName; } public void setUseCurrent(boolean useCurrent) { this.useCurrent = useCurrent; } public void setClose(boolean close) { this.close = close; } }
这个文件是把78行换做79行。
到此基本就完成了,大部分 都应该成功了。如果不成功,有可能是连接池使用问题,因为我本人也遇到该问题
我的数据源配置如下:
<!--dbcp 配数据源 --> <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@1.168.0.11:1521:orcl" /> <property name="username" value="xxx" /> <property name="password" value="xxx" /> </bean> --> <!-- 通过jndi的方式来调用datasource,即使不一定是在j2ee环境中也可以正常使用默认情况下,如果没有指定,"java:comp/env/"将放在后面jndi名称前面--> <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>jdbc/pt</value> </property> <!-- 如果你不想使用 'java:comp/env/'前缀的话请设置下面的值为false, 默认值为false --> <property name="resourceRef"> <value>true</value> </property> </bean>
因为我用的是tomcat 6.0 所以代码中这两种方式,估计都会有问题。
解决办法:
替换tomcat中的tomcat-dbcp.jar文件。
我用tomcat7.0中的tomcat-dbcp.jar 替换完就可以了。
写的不好,希望能帮助到你。
相关文章推荐
- spring4+hibernate4+springMvc 注解整合
- ssh2整合velocity出现Unable to find resource
- SpringMVC+Spring3.2+Hibernate4整合实例
- 关于struts+spring4+hibernate4整合是出现的No Session found for current thread解决
- struts2+spring3+hibernate4整合
- 【备忘】Struts2+Spring3+Hibernate4+Maven+EasyUI整合入门视频教程
- hibernate4整合spring3.1出现java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider
- iOS通讯录整合,兼容iOS789写法,附demo
- JBPM4.4整合SSH2项目
- SSH2整合dwr
- struts2+Hibernate4+spring3+EasyUI环境搭建之四:引入hibernate4以及spring3与hibernate4整合
- SSH2 整合登录
- struts2+spring4+hibernate4整合时 org.hibernate.service.jta.platform.spi.JtaPlatform 异常
- 使用Maven搭建Struts2+Spring3+Hibernate4的整合开发环境
- 【ssh2学习记录】3、关于ssh2框架整合以及hibernate的一些总结
- hibernate4整合spring3.1的过程中的异常问题
- spring整合hibernate4.。。。
- SSH2整合项目开发中spring配置文件applicationContext.xml分析
- maven整合ssh2框架的依赖配置
- ssh2项目整合 struts2.1+hibernate3.3+spring3 基于hibernate注解和struts2注解