JBPM通过Persistence加载JPA配置文件持久化

JBPM的持久化相关的概念主要包括以下几点:JPA,JTA,Hibernate,JNDI

选择Hibernate可以直接通过实体类,映射生成对应的数据库表,因为JBPM的工作引擎,很多中间状态信息,对应的实体类都是JBPM设计好的,通过JPA或者Hibernate相关的注解标记,在运行时,会自动在数据库上生成对应的表。方便快捷安全,因为本来JBPM和JPA都是Jboss社区的,所以选择JPA作为持久化的方式也可以理解。

在你的项目中,比如我的是Springboot的项目:

注意在resources下的META-INF目录下的persistence.xml这是JPA的持久化配置文件,如果没有的话可以自己copy一份

内容如下

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<persistence
        version="2.0"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd
  http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
        xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>jdbc/jbpm-ds</jta-data-source>
        <mapping-file>META-INF/JBPMorm.xml</mapping-file>
        <class>org.drools.persistence.info.SessionInfo</class>
        <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
        <class>org.drools.persistence.info.WorkItemInfo</class>
        <class>org.jbpm.persistence.correlation.CorrelationKeyInfo</class>
        <class>org.jbpm.persistence.correlation.CorrelationPropertyInfo</class>
        <class>org.jbpm.runtime.manager.impl.jpa.ContextMappingInfo</class>

        <class>org.jbpm.process.audit.ProcessInstanceLog</class>
        <class>org.jbpm.process.audit.NodeInstanceLog</class>
        <class>org.jbpm.process.audit.VariableInstanceLog</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
            <property name="hibernate.max_fetch_depth" value="3"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.connection.release_mode" value="after_transaction"/>
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"/>
        </properties>
    </persistence-unit>
</persistence>

 

按照JBPM官方的文档持久化部分的描述的核心代码如下(当然我自己改卡了一部分):

        EntityManagerFactory emf =
                Persistence.createEntityManagerFactory( "org.jbpm.persistence.jpa");
        Environment env = EnvironmentFactory.newEnvironment();
        env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );

// create a new KIE session that uses JPA to store the runtime state

        KieHelper kieHelper = new KieHelper();
        KieBase kbase = kieHelper.addResource(ResourceFactory.newClassPathResource("helloolsen.bpmn")).build();
        StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
        int sessionId = ksession.getId();

// invoke methods on your method here
        ksession.startProcess("business-application-kjar.helloolsen");
        ksession.dispose();

这个“org.jbpm.persistence.jpa”我当时看蒙蔽了,以为是扫描这个路径下相关的类或者包呢,但是一直报错,我就去官网看文档看了一眼这个persistence.xml文档,我定睛一看,尼玛的,

<persistence-unit name="org.jbpm.persistence.jpa" transaction-type="JTA">

好眼熟,原来对应的是这个name,刚开始这个name不是这样子的,是默认的,忘了什么了,就不管了

然后后面还是报,报什么

jdbc/jbpm-ds

找不到,然后我就去查了一下那个标签

<jta-data-source>,

不查不知道,一查原来这个persistence.xml的整个配置文件是JPA的配置文件,我还以为是JBPM相关的文件呢,

然后又一看,你猜怎么着,原来这个标签里面的内容是数据源(datasource)的名字,但是通过JNDI获取的,然后我就去spring的配置文件里面配置自己的数据源看能用不,配置如下:

spring.datasource.name=jdbc/jbpm-ds
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/jbpm
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

我以为这样配置了给个名字就行了谁知道这尼玛不行,我就寻思着是不是还可以再起一个jndi-name什么的,谁还没个外号是吧,然后我去查springboot的配置文件,果然有:

spring.datasource.jndi-name=jdbc/jbpm-ds

再加上这个jndi-name,但是还是获取不到jdbc/jbpm-ds,头疼,然后我就看官网的描述,说在java环境中可以加上这样的配置:

Properties driverProperties = new Properties();
driverProperties.put("user", "sa");
driverProperties.put("password", "sa");
driverProperties.put("url", "jdbc:h2:mem:jbpm-db;MVCC=true");
driverProperties.put("driverClassName", "org.h2.Driver");
driverProperties.put("className", "org.h2.jdbcx.JdbcDataSource");
PoolingDataSourceWrapper pdsw = DataSourceFactory.setupPoolingDataSource("jdbc/jbpm-ds", driverProperties);

我就懵逼了,这个pdsw配置到那里去呢?从上面的java代码里,我看了每个方法都没有添加数据源的地方,因为在我们的常识中实例化了数据源对象一般这个数据源对象都会被一个环境相关的初始化对象set进去,然后加载持久化信息。

可是谁知道呢?我就把代码copy进去试试

        // configure datasource
        Properties driverProperties = new Properties();
        driverProperties.put("user", "root");
        driverProperties.put("password", "123456");
        driverProperties.put("url", "jdbc:mysql://localhost:3306/jbpm");
        driverProperties.put("driverClassName", "com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
        driverProperties.put("className", "com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
        driverProperties.put("databaseName", "jbpm");
        driverProperties.put("portNumber", "3306");
        driverProperties.put("serverName", "localhost");
        PoolingDataSourceWrapper pdsw = DataSourceFactory.setupPoolingDataSource("jdbc/jbpm-ds", driverProperties);

// create the entity manager factory and register it in the environment
        EntityManagerFactory emf =
                Persistence.createEntityManagerFactory( "org.jbpm.persistence.jpa.test");
        Environment env = EnvironmentFactory.newEnvironment();
        env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );

// create a new KIE session that uses JPA to store the runtime state

        KieHelper kieHelper = new KieHelper();
        KieBase kbase = kieHelper.addResource(ResourceFactory.newClassPathResource("helloolsen.bpmn")).build();
        StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
        int sessionId = ksession.getId();

// invoke methods on your method here
        ksession.startProcess("business-application-kjar.helloolsen");
        ksession.dispose();

那个pdsw就像个孤儿一样在哪放着了,看着实属可怜,

但是还是报

jdbc/jbpm-ds

找不到,我是当时真得报这个错误了,如果你没报那你可真幸运,然后我就换另外一种方式,

我知道数据源配置都可以在server的容器初始化的时候在配置文件里配置就可以了,比如tomcat的conf/context.xml里面配置这些数据源信息,然后就可以JNDI获取,但是springboot是内嵌的tomcat也就是说没有这个配置文件了,我就想起来可以自定义tomcat了,但是仍然失败了,然后我就去看源码了,根据源码,然后就解决了,于是就变成了了这样的结果:

        Properties driverProperties = new Properties();
        driverProperties.put("user", "root");
        driverProperties.put("password", "123456");
        driverProperties.put("url", "jdbc:mysql://localhost:3306/jbpm");
        driverProperties.put("driverClassName", "com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
        driverProperties.put("className", "com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
        driverProperties.put("databaseName", "jbpm");
        driverProperties.put("portNumber", "3306");
        driverProperties.put("serverName", "localhost");
        PoolingDataSourceWrapper pdsw = DataSourceFactory.setupPoolingDataSource("jdbc/jbpm-ds", driverProperties);

// create the entity manager factory and register it in the environment
        EntityManagerFactory emf =
                Persistence.createEntityManagerFactory( "org.jbpm.persistence.jpa.test");
        Environment env = EnvironmentFactory.newEnvironment();
        env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );

// create a new KIE session that uses JPA to store the runtime state

        KieHelper kieHelper = new KieHelper();
        KieBase kbase = kieHelper.addResource(ResourceFactory.newClassPathResource("helloolsen.bpmn")).build();
        StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
        int sessionId = ksession.getId();

// invoke methods on your method here
        ksession.startProcess("business-application-kjar.helloolsen");
        ksession.dispose();

注意那个

driverClassName 不能写成com.mysql.jdbc.Driver这个是不对的要换成我代码里面那个XA的这个是支持XA事务的驱动器,感兴趣可以去了解一下XA事务,还有分布式事务什么的

然后persistence.xml的最终形态是:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<persistence
        version="2.0"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd
  http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
        xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <persistence-unit name="org.jbpm.persistence.jpa.test" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>jdbc/jbpm-ds</jta-data-source>
        <mapping-file>META-INF/JBPMorm.xml</mapping-file>
        <class>org.drools.persistence.info.SessionInfo</class>
        <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
        <class>org.drools.persistence.info.WorkItemInfo</class>
        <class>org.jbpm.persistence.correlation.CorrelationKeyInfo</class>
        <class>org.jbpm.persistence.correlation.CorrelationPropertyInfo</class>
        <class>org.jbpm.runtime.manager.impl.jpa.ContextMappingInfo</class>

        <class>org.jbpm.process.audit.ProcessInstanceLog</class>
        <class>org.jbpm.process.audit.NodeInstanceLog</class>
        <class>org.jbpm.process.audit.VariableInstanceLog</class>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
            <property name="hibernate.max_fetch_depth" value="3"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.connection.release_mode" value="after_transaction"/>
            <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"/>
        </properties>
    </persistence-unit>
</persistence>

再说一下各个部分,那个<class>标签是对应的要持久化的实体,也就是说,在JBPM执行business process(也被人翻译为工作流)的过程中的这些类中的信息都会被存储到数据库里面

<mapping-file>META-INF/JBPMorm.xml</mapping-file>

这个标签那个文件是hibernate的映射配置文件具体是什么文件可以自己查一下,有没有都无所谓的,

后面的property是hibernate相关特性的配置,具体可以逐条了解一下,

hibernate.hbm2ddl.auto

这个就比较重要了,举个例子如果你配置了value=update,那么如果这个实体类对应的表在数据库中不存在,他会根据在这个类上的注解自动在数据库里生成对应的表,并存储这个类对应的对象在各个时刻的数据,

 

看到左侧栏的表和中间面板里面的数据了吗?兄弟,就这样了,有什么问题可以留言

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章