`
salazar
  • 浏览: 31272 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

解决JBPM整合SPRING部署持久层疑问

    博客分类:
  • JBPM
阅读更多

       在研究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文件。

    有些口水话.....

2
0
分享到:
评论

相关推荐

    Jbpm4.4 整合Spring Hibernate4

    "Jbpm4.4 整合Spring Hibernate4" 指的是一个集成项目,其中JBPM(Job Business Process Management)版本4.4被整合到Spring框架和Hibernate ORM工具的环境中。JBPM是一个开源的工作流管理系统,用于处理业务流程的...

    jbpm4.0+ext3.0+spring+hibernate整合实例

    Hibernate在本整合实例中,可能是作为数据访问层,负责与数据库的交互,提供了便捷的数据持久化功能。 **整合实例** 将jbpm4.0、EXT3.0、Spring和Hibernate整合在一起,可以构建出一个功能强大的业务流程管理系统...

    ssh-jbpm整合

    SSH-JBPM整合是将Spring、Struts2和Hibernate这三个流行的Java开源框架与Business Process Management System(业务流程管理系统)JBPM结合使用的一种实践。SSH分别代表Spring(一个强大的依赖注入和面向切面编程...

    jbpm整合s2sh

    在jbpm整合中,Spring用于管理jbpm的工作流引擎实例,以及S2SH中的其他bean,确保组件之间的解耦合。 3. **Hibernate**:Hibernate是一个持久化框架,用于简化数据库操作。在jbpm整合中,Hibernate可能被用来管理...

    jbpm与ssh框架整合

    jBPM整合步骤 - 引入jBPM相关库到项目中。 - 配置jBPM的工作流引擎,如数据库连接、工作流目录等。 - 在Spring中配置jBPM的SessionFactory和Service,以便在业务逻辑中调用jBPM的服务。 - 设计和导入流程定义文件...

    jbpm+ssh整合

    【jbpm+ssh整合】是将企业级工作流引擎jbpm与流行的SSH(Struts、Spring、Hibernate)框架集成,实现一个完整的业务流程管理系统。jbpm是一个开源的工作流引擎,可以处理复杂的业务流程自动化,而SSH是Java开发中...

    ssh+jbpm整合实力

    在"ssh+jbpm整合实力"的项目中,我们可以看到将SSH框架与Jbpm工作流引擎进行了集成,用于实现一个发布文章的流程。这个流程可能涉及到文章的创建、审核、发布等多个环节,通过Jbpm的流程定义语言(BPMN)来设计和控制...

    Jbpm4与SSH整合

    它们分别负责控制层、视图层和持久层的处理,而JBPM4则是一个强大的工作流管理系统,用于处理业务流程的自动化。将JBPM4与SSH整合,可以实现业务流程与应用程序的无缝对接,提高开发效率,优化业务流程管理。 **1. ...

    jbpm整合ssh的例子

    【jbpm整合ssh的例子】是关于如何将Java业务流程管理(jbpm)系统与Spring(ssh中的S)、Struts(ssh中的s)和Hibernate(ssh中的h)这三大流行开源框架进行集成的一个示例项目。这个例子展示了在Tomcat应用服务器上...

    jbpm4.4 ssh 整合

    总的来说,SSH与JBPM 4.4的整合是一个强大的组合,它为Java企业级应用提供了完整的业务流程解决方案。开发者可以通过这个整合实现复杂流程的自动化,并在SSH框架的支撑下,享受到便捷的开发和维护体验。

    JBPM5.4 SSH 完整项目整合案例

    4. **Spring MVC**:作为Web层的解决方案,Spring MVC提供了模型-视图-控制器架构,使Web应用开发更为清晰和模块化。 5. **Spring上下文**:负责管理应用中的bean,包括初始化、装配和销毁等生命周期管理。 **SSH...

    ssh整合jbpm5.4

    在SSH与JBPM5.4的整合中,Spring通常被用作服务层的容器,管理Struts2和Hibernate的bean,同时作为与JBPM交互的桥梁。通过Spring的AOP,可以实现事务的统一管理和异常处理。Struts2负责前端展示和用户交互,而...

    jbpm4整合ssh框架

    - 然后,配置Spring,创建jbpm4的数据源、SessionFactory和ProcessEngine,以及流程定义的部署服务。 - 接着,编写Struts的Action类,定义业务操作,并在其中调用jbpm4的工作流API。 - 再次,利用Spring的AOP实现...

    JBPM5整合HH2完整项目

    这个项目旨在提供一个完整的业务流程管理(BPM)解决方案,利用JBPM5的强大功能来实现流程定义、执行和监控,同时结合了Spring的依赖注入和事务管理、Hibernate的对象关系映射以及Struts2的MVC架构,构建出高效、可...

    jbpm5+ssh集成

    - **数据访问**: Hibernate作为持久化层,处理jbPM5的数据操作,如流程实例、任务的CRUD操作。 - **实体映射**: jbPM5的数据模型可以通过Hibernate的实体类进行映射,简化数据库交互。 5. **集成步骤** - **配置...

    jbpm4与ssh整合

    整合jbpm4与SSH,主要是为了利用SSH的控制层和持久化层能力,配合jbpm4的流程引擎,实现流程的启动、暂停、恢复、终止等操作,并将流程中的任务分配给合适的用户或角色。以下是一些关键步骤: 1. **配置Spring**:...

    myeclipse的jBPM4.4整合ssh2.rar

    7. **整合jBPM与SSH2**:在Spring中配置jBPM的ServiceTaskExecutor,使业务流程能够调用服务层的方法。在Struts2中配置拦截器,处理流程的启动、暂停、继续、结束等操作。 8. **部署与测试**:在MyEclipse中部署...

    jbpm4.3所需jar包

    通过SSH与JBPM的整合,开发者可以构建出一个强大的企业级工作流管理系统,具备流程管理、用户认证、数据持久化和Web应用的前端控制能力。这个解决方案提供了源代码,意味着开发者可以直接查看和修改代码,根据需求...

    springmvc+hibernate+jbpm 开发OA源码

    【描述】"springmvc整合hibernate,jbpm实现快速开发办公系统"指出,此项目通过集成SpringMVC和Hibernate,实现了数据访问层和业务逻辑层的高效协作,提高了开发效率。同时,利用jBPM的流程管理能力,使得OA系统能够...

    JBPM4.4+SSH2完整整合jar包

    Hibernate则是一个持久层框架,负责将Java对象映射到关系数据库中,简化数据操作。 在这个整合包中,开发者可以找到所有必要的jar文件,包括JBPM的核心库、工作流引擎、流程设计工具以及SSH框架的相关组件。例如,...

Global site tag (gtag.js) - Google Analytics