I'm working on a jBPM project now and I can't get jBPM to persist its state into the DB. After I run a process, I see no records in the tables. I expect to see records in processinstancelog, sessioninfo or nodeinstancelog, but there's none. I use PostgreSQL.
persistence.xml
<persistence version="2.0"
xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="org.jbpm.domain" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/datasources/TestDS</jta-data-source>
<mapping-file>META-INF/Taskorm.xml</mapping-file>
<mapping-file>META-INF/JBPMorm.xml</mapping-file>
<mapping-file>META-INF/Executor-orm.xml</mapping-file>
<mapping-file>META-INF/Servicesorm.xml</mapping-file>
<mapping-file>META-INF/TaskAuditorm.xml</mapping-file>
<!-- engine -->
<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>
<!-- bam -->
<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.PostgreSQLDialect"/>
<property name="hibernate.max_fetch_depth" value="3"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.id.new_generator_mappings" value="false"/>
<property name="hibernate.transaction.jta.platform"
value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>
</properties>
</persistence-unit>
</persistence>
My Java method that invokes jBPM
public Response test() {
KieServices kieServices = KieServices.Factory.get();
KieContainer kContainer = kieServices.getKieClasspathContainer();
KieBase kBase = kContainer.getKieBase();
KieSession ksession = kBase.newKieSession();
ksession.getWorkItemManager().registerWorkItemHandler("Human Task", new WorkItemHandler() {
@Override
public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
System.out.println("executeWorkItem done");
}
@Override
public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
System.out.println("abortWorkItem done");
}
});
Map<String, Object> params = new HashMap<String, Object>();
params.put("name", "world");
ProcessInstance proc = ksession.startProcess("test-project.sample", params);
System.out.println("ID: " + proc.getId());
return Response.status(200).entity("ok " + proc.getId()).build();
}
After I created the Test schema in DB and run the code, I see that it has created tables, but they all are empty.
Any suggestions?
When you need to use jBPM for process execution, you should always use RuntimeEnvironment for setting up your environment and then access the engine via RuntimeManager/RuntimeEngine. RuntimeEnvironment will allow you to configure your process execution with EntityManagerFactory which is usually bound to some specific Persistence Unit.
You can check this approach if you generate jBPM Hello World application in Eclipse.
Some code:
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieBase kbase = kContainer.getKieBase("kbase");
RuntimeManager manager = createRuntimeManager(kbase);
RuntimeEngine engine = manager.getRuntimeEngine(null);
KieSession ksession = engine.getKieSession();
and createRuntimeManager method:
private static RuntimeManager createRuntimeManager(KieBase kbase) {
JBPMHelper.startH2Server();
JBPMHelper.setupDataSource();
EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");
RuntimeEnvironmentBuilder builder = RuntimeEnvironmentBuilder.Factory.get()
.newDefaultBuilder().entityManagerFactory(emf)
.knowledgeBase(kbase);
return RuntimeManagerFactory.Factory.get()
.newSingletonRuntimeManager(builder.get(), "com.sample:example:1.0");
}
Also, good practise is to create RuntimeManager only once and then get RuntimeEngine from it anytime you need to interact with processes.