jbpm4 整合SSH2 兼容 hibernate4
来源:互联网 发布:Mac OS X Capitan 编辑:程序博客网 时间:2024/06/01 10:18
废话不多说,jbpm4默认支持hibernate3.
整合过程如下:
研究过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的表与实体的映射文件,如下:
到这里,算完了吗?还没有!前面说过,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 替换完就可以了。
写的不好,希望能帮助到你。
4 0
- jbpm4 整合SSH2 兼容 hibernate4
- jbpm4.4 hibernate4 的兼容整合
- JBPM4.4与SSH2整合
- JBPM4.4整合SSH2项目
- SSH2+JBPM4.4 整合常见错误
- JBPM4.4与SSH2之整合
- JBPM4.4+SSH2 Demo
- 基于J2EE平台下SSH2+JBPM4.4+ExtJs4.1 框架整合&项目实战
- SSH2 整合
- ssh2整合
- SSH2整合
- SSH2 整合
- Myeclipse10整合ssh2(struts2.1+spring3.1+hibernate4.1)+零注解零配置
- ssh2 + jbpm4.4+ myflow-min示例项目
- ExtJs4.1+Jbpm4+SSH2+Oracle10g视频教程
- SSH+JBPM4+Tomcat6整合
- SSH整合JBPM4.4
- SSH整合JBPM4.4
- java 零碎知识随笔
- 能转换成多种格式的PDF转换器
- Oracle 存储过程发送邮件
- url 重写
- Linux内核模块的加载 insmod
- jbpm4 整合SSH2 兼容 hibernate4
- 获取apk签名信息
- WAN和LAN的区别
- 使用mysqldump导出数据库
- Java Web Service相关的若干概念(JAX-WS,JAX-RS)
- android 选取相册图片
- 10年程序员谈.Net程序员的职业规划(图/文)
- Cocos2d-x 3.0 主线程
- 何为大端序,小端序?