13.5. Using Persistence

JBoss BPM Suite engine does not save runtime data persistently by default. To use persistence, you need to:
  • Add necessary dependencies.
  • Configuring a datasource.
  • Configure the JBoss BPM Suite engine.

13.5.1. Adding Dependencies

To use persistence, add necessary dependencies to the classpath of your application. If you are using JBoss Development Studio with JBoss BPM Suite runtime default configuration, all necessary dependencies are already present for the default persistence configuration. Otherwise, ensure that the necessary JAR files are added to your JBoss BPM Suite runtime directory.
Following is a list of dependencies for the default combination with Hibernate as the JPA persistence provider, an H2 in-memory database, and Bitronix for JTA-based transaction management. Dependencies needed for your project will vary depending on your solution configuration.
  • jbpm-persistence-jpa.jar file is necessary for saving the runtime state. Therefore, always make sure it is available in your project.
  • jbpm-persistence-jpa (org.jbpm)
  • drools-persistence-jpa (org.drools)
  • persistence-api (javax.persistence)
  • hibernate-entitymanager (org.hibernate)
  • hibernate-annotations (org.hibernate)
  • hibernate-commons-annotations (org.hibernate)
  • hibernate-core (org.hibernate)
  • commons-collections (commons-collections)
  • dom4j (dom4j)
  • jta (javax.transaction)
  • btm (org.codehaus.btm)
  • javassist (javassist)
  • slf4j-api (org.slf4j)
  • slf4j-jdk14 (org.slf4j)
  • h2 (com.h2database)

13.5.2. Manually Configuring JBoss BPM Suite Engine to Use Persistence

Use JPAKnowledgeService to create a knowledge session based on a knowledge base, a knowledge session configuration (if necessary), and the environment. Ensure that the environment contains a reference to your Entity Manager Factory. For example:

// create the entity manager factory and register it in the environment

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

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

StatefulKnowledgeSession ksession = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
int sessionId = ksession.getId();

// invoke methods on your method here

ksession.startProcess( "MyProcess" );
ksession.dispose();
Additionally, you can use JPAKnowledgeService to recreate a session based on a specific session id. For example:
// recreate the session from database using the sessionId

ksession = JPAKnowledgeService.loadStatefulKnowledgeSession(sessionId, kbase, null, env );
Note that only the minimal state that is required to continue execution of the process instance is saved. You cannot retrieve information related to already executed nodes if that information is no longer necessary. To search for history-related information, use the history log.
Add persistence.xml to META-INF to configure JPA. Following example uses Hibernate and H2 database:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistenc 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>

    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
      <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.transaction.jta.platform"
                value="org.hibernate.service.jta.platform.internal.BitronixJtaPlatform"/>
    </properties>
  </persistence-unit>

</persistence>
In this example, persistence.xml refers to a data source called jdbc/jbpm-ds. If you run your application in an application server, these containers typically allow you to use custom configure file for the data sources. Refer your application server documentation for further details.
Following example shows you how to set up a data source:
PoolingDataSource ds = new PoolingDataSource();
ds.setUniqueName("jdbc/jbpm-ds");
ds.setClassName("bitronix.tm.resource.jdbc.lrc.LrcXADataSource");
ds.setMaxPoolSize(3);
ds.setAllowLocalTransactions(true);
ds.getDriverProperties().put("user", "sa");
ds.getDriverProperties().put("password", "sasa");
ds.getDriverProperties().put("URL", "jdbc:h2:mem:jbpm-db");
ds.getDriverProperties().put("driverClassName", "org.h2.Driver");
ds.init();