之前一直报错,郁闷了很久:
[...]
nested exception is org.hibernate.MappingException: Unknown entity: org.jbpm.pvm.internal.id.PropertyImpl
at
[...]
但是,该类的hibernate映射文件是写在jar包里面的。Hibernate为何没有解析到这个配置文件,不得而知。查看jbpm.hibernate.cfg.xml文件:
Xml代码
<mapping resource="jbpm.repository.hbm.xml" />
<mapping resource="jbpm.execution.hbm.xml" />
<mapping resource="jbpm.history.hbm.xml" />
<mapping resource="jbpm.task.hbm.xml" />
<mapping resource="jbpm.identity.hbm.xml" />
PropertyImpl的映射就在第一个被引入进来的文件当中,可以猜想到,其实整个的jbpm.hibernate.cfg.xml文件都没有Hibernate找到。
查看两种事务控制方式对应的配置文件jbpm.tx.spring.cfg.xml和jbpm.tx.hibernate.cfg.xml,发现后者会默认地去读classpath中的jbpm.hibernate.cfg.xml文件,而使用spring的时候却没有这样的操作(在applicationContext.xml文件中配置嘛)。
另外,在查看源码的时候,到处可见的是默认配置"jbpm.cfg.xml":
Java代码
/**
* @author Joram Barrez
*/
public class SpringHelper implements ApplicationContextAware {
protected ApplicationContext applicationContext;
protected String jbpmCfg = "jbpm.cfg.xml";
...
却看不到jbpm.hibernate.cfg.xml的默认值。jbpm的配置文件设计思想逐渐明晰:
总的配置从jbpm.cfg.xml开始,你可以更改这个文件以便使用自己的事务控制方式。
如果使用的是hibernate的事务控制,那么你就得提供好jbpm.tx.hibernate.cfg.xml文件,并做好配置。如果使用的是spring的事务控制,只需要在jbpm.cfg.xml文件中切换到spring中即可,其他的关于数据库连接信息,sessionFactory等等由你自己到applicationContext文件中配置即可。
以下是在applicationContxt.xml文件中配置的关于jbpm信息:
Xml代码
<!-- 业务系统 -->
<bean id="crmSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="crmDataSource" />
<!-- 引入外部配置文件,将jbpm和CRM的配置信息放到一起 -->
<property name="configLocation" value="classpath:jbpm.hibernate.cfg.xml"></property>
<!-- 扫描指定目录下的所有实体属性映射配置文件 -->
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/cn/chinacti/crm/entity</value>
</list>
</property>
</bean>
如此,我的问题得以解决。
道理很简单,以后记得,与Spring 集成,那么所有的数据库信息都应该从applicationContext.xml配置出发,而不应让集成进来的组件自己去找自己的配置文件。
========================================
多数据源的情况下spring与jbpm4.4的整合:
网络上有有很多关于jbpm4与spring整合的帖子,但都是关于单一数据源的,当系统中含有多数据源交由spring管理的时候,对jbpm4的整合就要稍微修改下,废话不多说上代码:
===========================applicationContext-database-jbpm.xml==================================
applicationContext-database-jbpm.xml(spring配置文件)
<?xml version="1.0"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="jbpm_dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jndi/cnas/jbpm4"></property>
</bean>
<bean id="sessionFactory_j" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="jbpm_dataSource" />
<!-- bean 用来查找即便不在同一xml文件中也可 -->
</property>
<!-- 引入外部配置文件,将jbpm和CRM的配置信息放到一起 -->
<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>
<property name="mappingResources">
<list>
<!-- 自定义的流程节点与角色配置关系表 -->
<value>config/hibernate/jbpm/processRoleConfig.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<!--jbpm4.4工作流 -->
<!-- 重点,此处指向继承springHelper的自定类,用以指定特定的数据源 -->
<bean id="springHelper" class="com.utils.ProcessEngineFactoryBean">
<property name="jbpmCfg" value="config/jbpm/jpdl/spring-jbpm4.cfg.xml" />
<property name="sessionFactory">
<ref local="sessionFactory_j" />
<!-- local标注是指找到同一xml文件中的对象 -->
</property>
</bean>
<bean id="processEngine" factory-bean="springHelper" factory-method="createProcessEngine" />
<bean id="transactionManage_jbpm" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory_j" />
</property>
</bean>
<!---->
<bean id="hibInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
<property name="sessionFactory">
<ref local="sessionFactory_j" />
</property>
</bean>
<!-- 配置Transaction拦截器 -->
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManage" />
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 工作流Message类 -->
<bean id="JbpmCommonServiceFaction" class="com.cnas.dpms80000.service.JbpmCommonService">
<property name="processEngine">
<ref local="processEngine" />
</property>
</bean>
<bean id="JbpmCommonService" factory-method="getInstance" factory-bean="JbpmCommonServiceFaction"></bean>
<!-- 流程节点与角色配置关系 -->
<bean id="ProcessRoleConfigDao" class="com.cnas.db.dao.jbpm.impl.ProcessRoleConfigDaoImpl">
<property name="sessionFactory">
<ref bean="sessionFactory_j" />
</property>
</bean>
<bean id="HRDispatchProcessNodeRoleConfigService" class="com.cnas.dpms80001.service.impl.HRDispatchProcessNodeRoleConfigServiceImpl">
<property name="prConfigDao">
<ref bean="ProcessRoleConfigDao" />
</property>
</bean>
</beans>
=================================ProcessEngineFactoryBean类=======================================
package com.utils;
import org.hibernate.SessionFactory;
import org.jbpm.api.ProcessEngine;
import org.jbpm.pvm.internal.cfg.ConfigurationImpl;
import org.jbpm.pvm.internal.processengine.SpringHelper;
/**
* 在spring的多数据源情况下,重写jbpm的springHelper类,用以指定多数据源中某特定数据源
*
* @author jKF65104
*
*/
public class ProcessEngineFactoryBean extends SpringHelper {
protected SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public ProcessEngine createProcessEngine() {
processEngine = new ConfigurationImpl().springInitiated(applicationContext).setResource(jbpmCfg)
.setHibernateSessionFactory(sessionFactory).buildProcessEngine();
return processEngine;
}
}
=================================================spring-jbpm4.cfg.xml(没啥不同的这里)=================================================
<?xml version="1.0" encoding="UTF-8"?>
<jbpm-configuration>
<process-engine-context>
<string name="spring.cfg" value="spring-jbpm4.xml" />
</process-engine-context>
<import resource="jbpm.default.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.businesscalendar.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" /> -->
</jbpm-configuration>
===========================================================
以上可以看出当存在多数据源的情况下,官方提供的spring实例中的springHelper中的数据源获取获取默认的某个sessionFactory对象。