在研究JBPM,要应用到项目开发之中,由于系统使用spring作为业务层管理,而JBPM默认使用的hibernate作为持久层管理。我需要将它们集成在一起,幸运的是spring与hibernate本身就有完全兼容的集成应用方案,但是之中还是遇到不少问题。
我这使用的JBPM版本是3.1.2,下载的包是jbpm-starters-kit-3.1.2.zip。
首先要将JBPM持久层部分通过系统自动持久化(使用内存数据库hsqldb除外)。我们先将JBPM部署持久层需要的jar包摘出来,虽然JBPM应用需要不少jar包,但是部署持久层并不是需要很多,清单如下:
jar包 |
路径(BaseDir = jbpm-starters-kit-3.1.2) |
说明 |
hibernate3 |
BaseDir \jbpm\lib\hibernate\ |
hibernate核心程序,版本3.1 |
spring |
需要下载 |
Spring核心程序,这里使用的版本是2.0 |
jbpm-3.1.2 |
BaseDir \jbpm\build\ |
JBPM核心程序 |
dom4j-1.6.1 |
BaseDir \jbpm\lib\dom4j\ |
支持解析xml核心程序 |
spring-modules-jbpm31 |
需要下载 |
spring与jbpm集成支持包 |
jboss-j2ee |
BaseDir \jbpm\lib\jboss\ |
JBOSS支持JBPM需要的java程序 |
cglib-2.1_2jboss |
BaseDir \jbpm\lib\jboss\ |
支持JOSS-J2EE和hibernate.tool.hbm2ddl,如果不使用会报错: java.lang.NoClassDefFoundError: net/sf/cglib/proxy/CallbackFilter
|
bsh |
BaseDir \jbpm\lib\jboss\ |
支持JOSS-J2EE,如果不使用会报错:bsh/EvalError |
asm |
BaseDir \jbpm\lib\jboss\ |
支持JOSS-J2EE,如果不使用会报错: org/objectweb/asm/Type |
antlr-2.7.5H3 |
BaseDir \jbpm\lib\jboss\ |
支持JOSS-J2EE,如果不使用会报错: antlr/ANTLRException |
ehcache-1.1 |
BaseDir \jbpm\lib\hibernate\ |
如果使用hibernate缓存则需要 |
ehcache-1.1 |
BaseDir \jbpm\lib\hibernate\ |
如果使用hibernate缓存则需要 |
除了上面的jar之外,还需要支持数据库的一些jar包。下面还需要JBPM提供的一些XML配置文件,具体清单如下:
文件名
|
路径
|
说明
|
default.jbpm.cfg.xml
|
jbpm-3.1.2,jar\org\jbpm\
|
jbpm主配置文件
|
ehcache.xml
|
BaseDir \jbpm\src\config.files\
|
如果使用hibernate缓存则需要配置
|
hibernate.cfg.xml
|
BaseDir \jbpm\src\config.files\
|
???,后面具体说明
|
下面可以开始spring的配置了,要让系统自动持久化JBPM持久层,我们得先连上数据库,在spring中我们使用org.apache.commons.dbcp.BasicDataSource类作为数据源连接(需要commons-dbcp.jar支持)。例如:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:oracle"></property>
... 省略若干
</bean>
然后我们使用spring集成hibernate来建立数据库会话工厂SessionFactory
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="mappingLocations">
<value>classpath*:org/jbpm/**/*.hbm.xml</value>
</property>
</bean>
接下来我们要配置的就是JBPM比较关键的BEAN,即jbpmConfiguration;
<bean id="jbpmConfiguration" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
<property name="configuration" value="classpath:default.jbpm.cfg.xml" />
</bean>
配置其实很简单,只要将主配置xml文件放在src目录下,按照上面配置就可以,那么问题出来了,如何让它自动部署呢?
JBPM本身提供jbpmConfiguration.createSchema方法来实现,而可以通过硬编码方式,或者在IOC配置jbpmConfiguration中加入〈property name="createSchema" value="true" /〉实现;
我们使用第一种方式看看效果;我这里已经做好了一个监听ServletContextListener,实现方法如下:
public void contextInitialized(ServletContextEvent sce) {
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
JbpmConfiguration jbpmConfiguration = (JbpmConfiguration)ctx.getBean("jbpmConfiguration");
try{
jbpmConfiguration.createSchema();
}catch(Exception e) {
e.printStackTrace();
}
}
最终控制台输出为:org.hibernate.HibernateException: hibernate.cfg.xml not found,缺少这个配置文件;看来这种方式启动,这个文件是不可缺了;那么我们在src添上这个文件再运行看看效果;
第二次控制台输出为:org.hibernate.HibernateException: The dialect was not set. Set the property hibernate.dialect. 这是怎么回事?
从网上我也找到很多关于这样的配置,例如网上配置如下:
<bean id="jbpmConfiguration" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
<property name="configuration" value="classpath:default.jbpm.cfg.xml" />
<property name="sessionFactory" ref="sessionFactory" />
<property nname="createSchema" value="true" />
</bean>
如果按照建立单独数据源dataSource,还是会出现这样的错误,除非使用hibernate.cfg.xml配置数据源;那么我们要使用单独的数据源部署应该怎么做?
由于是 jbpmConfiguration.createSchema();方法报出的错误,我们先将错误详细信息打印出来:
org.hibernate.HibernateException: The dialect was not set. Set the property hibernate.dialect.
at org.hibernate.dialect.Dialect.getDialect(Dialect.java:607)
at org.hibernate.dialect.Dialect.getDialect(Dialect.java:629)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:89)
at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.java:64)
at org.jbpm.persistence.db.DbPersistenceServiceFactory.getSchemaExport(DbPersistenceServiceFactory.java:76)
at org.jbpm.persistence.db.DbPersistenceServiceFactory.createSchema(DbPersistenceServiceFactory.java:107)
at org.jbpm.JbpmConfiguration.createSchema(JbpmConfiguration.java:415)
看见在调用createSchema方法时,在方法体调用getSchemaExport方法中有段代码:
public synchronized SchemaExport getSchemaExport() {
if (schemaExport==null) {
log.debug("creating schema export");
schemaExport = new SchemaExport(getConfiguration());
}
return schemaExport;
}
可以看见创建初始化SchemaExport对象,我们先看创建这个对象的参数getConfiguration()方法:
public synchronized Configuration getConfiguration() {
if (configuration==null) {
String hibernateCfgXmlResource = null;
if (JbpmConfiguration.Configs.hasObject("resource.hibernate.cfg.xml")) { // 如果配置里含有resource.hibernate.cfg.xml项,那么读这个配置对应的文件
hibernateCfgXmlResource = JbpmConfiguration.Configs.getString("resource.hibernate.cfg.xml");
}
......省略若干
configuration = HibernateHelper.createConfiguration(hibernateCfgXmlResource, hibernatePropertiesResource);
}
return configuration;
}
这里说读resource.hibernate.cfg.xml里的配置,我们可以打开JbpmConfiguration的配置文件default.jbpm.cfg.xml,看到确实是有这个配置,那么注释掉行吗?答案是不行的,最后在createConfiguration方法里还是会默认加载classpath:hibernate.cfg.xml,这是hibernate默认规定的,如果这个文件也没有,则就报错hibernate.cfg.xml not found;
那么就是说这里初始化SchemaExport对象的环境变量就必须是从hibernate.cfg.xml这里配置的,对应到org.hibernate.tool.hbm2ddl.SchemaExport.89行方法调用getDialect方法出错;我们跟进到源码看见getDialect方法是这么写的:
public static Dialect getDialect() throws HibernateException {
String dialectName = Environment.getProperties().getProperty( Environment.DIALECT );
if ( dialectName == null ) throw new HibernateException( "The dialect was not set. Set the property hibernate.dialect." );
....
}
意思是从环境变量属性中获取DIALECT 属性名称dialectName如果是空,则报错。
看来我误会了JBPM例子的意思,使用JbpmConfiguration.createSchema方法的方式创建表结构要求是指定hibernate配置(也就是必须要在hibernate.cfg.xml里指定hibernate.properties配置信息),如果不配置hibernate-properties那么必然会出现这样缺少环境变量或缺少数据源信息的错误;
如果是这样,那么解决这个问题?我们要先知道我们的目的是什么?
就是将hibernate配置的持久层配置信息持久化到指定的数据库。那么JbpmConfiguration.createSchema
方法是不是自由JOSS-JBPM独有的呢?我们还是看源码分析,还是从这个方法入口进去,看见persistenceServiceFactory.createSchema();方法,继续跟进,发现getSchemaExport()方法,而这个方法是关键,即也是错误at org.jbpm.persistence.db.DbPersistenceServiceFactory.createSchema中指定的位置。好的这下我们可以再跟进发现一段代码schemaExport = new SchemaExport(getConfiguration());是它才能够调用create创建脚本方法,而SchemaExport并不是JBPM自身有的。
这好像有些废话,用过hibernate的都知道hibernate本身就有Create-Schema功能,源码在org.hibernate.tool.hbm2ddl包下,配置属性为:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="dataSource" />
</property>
<property name="mappingLocations">
<value>classpath*:org/jbpm/**/*.hbm.xml</value>
</property>
<property name="hibernateProperties">
<props><prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
</bean>
好的为了不再说废话hibernate.hbm2ddl.auto,大家可以自己查阅资料。再次部署测试......等待......终于创建成功了。但是还有个问题是hibernate.hbm2ddl.auto-create是在什么时候创建的呢?它是为什么能成功,而jbpmConfiguration.createSchema()不行?
那我们依然看源码,既然是配在LocalSessionFactoryBean类下,就从这里看起。先思考,持久化肯定是在连接数据源,并生成会话之后才能够创建持久模型阿,又从源码上看这个类除了基本的set、get方法外,就只剩afterPropertiesSet中的buildSessionFactory。在此方法里我们可以发现一条代码:
if (this.hibernateProperties != null) {
// Add given Hibernate properties to Configuration.
config.addProperties(this.hibernateProperties);
}
即添加hibernate配置属性,这就对应了IOC里配置的hibernateProperties项,再看最后的newSessionFactory方法中:
Environment.verifyProperties( properties ); //在这里环境变量已经被注入进来了
Properties copy = new Properties();
copy.putAll( properties );
PropertiesHelper.resolvePlaceHolders( copy );
Settings settings = buildSettings( copy ); // 而最后将hibernateProperties配置,转化为对应的settings类
return new SessionFactoryImpl(
this,
mapping,
settings,
getInitializedEventListeners()
);
跟进SessionFactoryImpl构造函数,发现在295行中有这么段代码:
if ( settings.isAutoCreateSchema() ) new SchemaExport(cfg, settings).create(false, true); 这不就是自动持久化的判断吗?终于真像大白了,我们再总结下这个问题:
1,采用JBPMConfiguration.createSchema方法,在初始化SchemaExport时用到的环境变量必须是从hibernate.cfg.xml来的,而这个文件如果不指定全hibernate信息,则会报错。
2,如果让createSchema是在创建SessionFactory时,所用到的环境变量可以是从IOC容器里配置的,所以甚至可以不使用hibernate.cfg.xml文件。
有些口水话.....
分享到:
相关推荐
"Jbpm4.4 整合Spring Hibernate4" 指的是一个集成项目,其中JBPM(Job Business Process Management)版本4.4被整合到Spring框架和Hibernate ORM工具的环境中。JBPM是一个开源的工作流管理系统,用于处理业务流程的...
Hibernate在本整合实例中,可能是作为数据访问层,负责与数据库的交互,提供了便捷的数据持久化功能。 **整合实例** 将jbpm4.0、EXT3.0、Spring和Hibernate整合在一起,可以构建出一个功能强大的业务流程管理系统...
SSH-JBPM整合是将Spring、Struts2和Hibernate这三个流行的Java开源框架与Business Process Management System(业务流程管理系统)JBPM结合使用的一种实践。SSH分别代表Spring(一个强大的依赖注入和面向切面编程...
在jbpm整合中,Spring用于管理jbpm的工作流引擎实例,以及S2SH中的其他bean,确保组件之间的解耦合。 3. **Hibernate**:Hibernate是一个持久化框架,用于简化数据库操作。在jbpm整合中,Hibernate可能被用来管理...
jBPM整合步骤 - 引入jBPM相关库到项目中。 - 配置jBPM的工作流引擎,如数据库连接、工作流目录等。 - 在Spring中配置jBPM的SessionFactory和Service,以便在业务逻辑中调用jBPM的服务。 - 设计和导入流程定义文件...
【jbpm+ssh整合】是将企业级工作流引擎jbpm与流行的SSH(Struts、Spring、Hibernate)框架集成,实现一个完整的业务流程管理系统。jbpm是一个开源的工作流引擎,可以处理复杂的业务流程自动化,而SSH是Java开发中...
在"ssh+jbpm整合实力"的项目中,我们可以看到将SSH框架与Jbpm工作流引擎进行了集成,用于实现一个发布文章的流程。这个流程可能涉及到文章的创建、审核、发布等多个环节,通过Jbpm的流程定义语言(BPMN)来设计和控制...
它们分别负责控制层、视图层和持久层的处理,而JBPM4则是一个强大的工作流管理系统,用于处理业务流程的自动化。将JBPM4与SSH整合,可以实现业务流程与应用程序的无缝对接,提高开发效率,优化业务流程管理。 **1. ...
【jbpm整合ssh的例子】是关于如何将Java业务流程管理(jbpm)系统与Spring(ssh中的S)、Struts(ssh中的s)和Hibernate(ssh中的h)这三大流行开源框架进行集成的一个示例项目。这个例子展示了在Tomcat应用服务器上...
总的来说,SSH与JBPM 4.4的整合是一个强大的组合,它为Java企业级应用提供了完整的业务流程解决方案。开发者可以通过这个整合实现复杂流程的自动化,并在SSH框架的支撑下,享受到便捷的开发和维护体验。
4. **Spring MVC**:作为Web层的解决方案,Spring MVC提供了模型-视图-控制器架构,使Web应用开发更为清晰和模块化。 5. **Spring上下文**:负责管理应用中的bean,包括初始化、装配和销毁等生命周期管理。 **SSH...
在SSH与JBPM5.4的整合中,Spring通常被用作服务层的容器,管理Struts2和Hibernate的bean,同时作为与JBPM交互的桥梁。通过Spring的AOP,可以实现事务的统一管理和异常处理。Struts2负责前端展示和用户交互,而...
- 然后,配置Spring,创建jbpm4的数据源、SessionFactory和ProcessEngine,以及流程定义的部署服务。 - 接着,编写Struts的Action类,定义业务操作,并在其中调用jbpm4的工作流API。 - 再次,利用Spring的AOP实现...
这个项目旨在提供一个完整的业务流程管理(BPM)解决方案,利用JBPM5的强大功能来实现流程定义、执行和监控,同时结合了Spring的依赖注入和事务管理、Hibernate的对象关系映射以及Struts2的MVC架构,构建出高效、可...
- **数据访问**: Hibernate作为持久化层,处理jbPM5的数据操作,如流程实例、任务的CRUD操作。 - **实体映射**: jbPM5的数据模型可以通过Hibernate的实体类进行映射,简化数据库交互。 5. **集成步骤** - **配置...
整合jbpm4与SSH,主要是为了利用SSH的控制层和持久化层能力,配合jbpm4的流程引擎,实现流程的启动、暂停、恢复、终止等操作,并将流程中的任务分配给合适的用户或角色。以下是一些关键步骤: 1. **配置Spring**:...
7. **整合jBPM与SSH2**:在Spring中配置jBPM的ServiceTaskExecutor,使业务流程能够调用服务层的方法。在Struts2中配置拦截器,处理流程的启动、暂停、继续、结束等操作。 8. **部署与测试**:在MyEclipse中部署...
通过SSH与JBPM的整合,开发者可以构建出一个强大的企业级工作流管理系统,具备流程管理、用户认证、数据持久化和Web应用的前端控制能力。这个解决方案提供了源代码,意味着开发者可以直接查看和修改代码,根据需求...
【描述】"springmvc整合hibernate,jbpm实现快速开发办公系统"指出,此项目通过集成SpringMVC和Hibernate,实现了数据访问层和业务逻辑层的高效协作,提高了开发效率。同时,利用jBPM的流程管理能力,使得OA系统能够...
Hibernate则是一个持久层框架,负责将Java对象映射到关系数据库中,简化数据操作。 在这个整合包中,开发者可以找到所有必要的jar文件,包括JBPM的核心库、工作流引擎、流程设计工具以及SSH框架的相关组件。例如,...