0 Replies Latest reply on Aug 30, 2012 12:43 PM by Anatoliy Kalenskiy

    Non JPA transaction management for JBPM 5.3.0 or how to integrate JBPM with current application that use HibernateTransactionManager ?

    Anatoliy Kalenskiy Newbie

      Hi all,

       

      I have an application - Spring+Hibernate.

      All transactions management described in spring config:

       

      <bean id="transactionManager"

                class="org.springframework.orm.hibernate4.HibernateTransactionManager">

              <property name="dataSource" ref="dataSource"/>

              <property name="sessionFactory" ref="sessionFactory"/>

          </bean>

       

          <!-- enables the configuration of transactional behavior based on annotations -->

          <tx:annotation-driven transaction-manager="transactionManager"/>

       

      So in code we just use:

       

      @Transactional(propagation = Propagation.REQUIRES_NEW)
          public void handleEvent(Event event) {
           List<EventAction> eventActions =  event.getEventactions();
                for(EventAction action : eventActions) {
                      actions.run();
            }
      }
      

        So all actions runs in one transaction. Now we want to use  JBPM process to run such actions.

      We create some jbpm process com.example.process and  rewrite our code to :

      @Transactional(propagation = Propagation.REQUIRES_NEW)
          public void handleEvent(Event event) {
           List<EventAction> eventActions =  event.getEventactions();
           Map<String, EventAction> actions = new HashMap<String, EventAction>();
      
            for(EventAction action : eventActions) {
                      actions.put(action.getDisplayName(), action);
             }
      
                Map<String, Object> params = new HashMap<String, Object>();
                params.put("event", event);
                params.put("actions", actions);
                ksession.startProcess("com.example.process", params);
      }
      

       

      The main Idea to run each actions in order depending on some specisic order (by DisplayName). So my diagram of the process consist of sequential Service task which hadler looks like:

       

      public class EventActionHandler implements WorkItemHandler {
          @Override
          public void executeWorkItem(WorkItem workItem, WorkItemManager workItemManager) {
      
              String displayName= (String) workItem.getParameter("DisplayName");
              Map<String, EventAction> actions = ( Map<String, EventAction>)  workItem.getParameter("actions");
      
              try {
                  (actions.get(displayName)).run();
                  System.out.println("run "+displayName+" done");
              } catch (Exception e) {
                  System.out.println("Exception "+displayName+" : " + e);
              }
              workItemManager.completeWorkItem(workItem.getId(),null);
          }
      ...
       }
      

      So each Service Task has it display name and this display name defines order . All works fine. I even can debug it. But now I want to see current status of the process -which one Service Task is executing now.

      I what to use for it JBPM console. I have configured all war-s from jbpm-installer_5.3.0 to use my Oracle schema. And I can see my process in JBPM Console -> process-> Process Overview .

      But I whant to see current instances of such processes. As I understand (to store in DB nessesary data for process instancess) I should do steps described in :

      jbpm-5.3.0.Final-docs/jbpm-docs/html_single/index.html

      19.3. Spring

       

      After words :

      The following example shows a slightly more complex example, where the session is configured to use persistence (JPA using an in-memory database) and transaction (using the Spring transaction manager).

      I've done it and my configuration is:

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:jbpm="http://drools.org/schema/drools-spring"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                                 http://drools.org/schema/drools-spring http://drools.org/schema/drools-spring.xsd ">
      
          <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
               <property name="dataSource" ref="dataSource"/>
               <property name="persistenceUnitName" value="org.jbpm.persistence.jpa"/>
           </bean>
      
           <bean id="JPAtxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
                 <property name="entityManagerFactory" ref="entityManagerFactory"/>
           </bean>
      
          <jbpm:kbase id="kbase">
              <jbpm:resources>
                  <jbpm:resource type="BPMN2" source="classpath:Events.bpmn"/>
               </jbpm:resources>
          </jbpm:kbase>
          <jbpm:ksession id="ksession" type="stateful" kbase="kbase">
              <jbpm:configuration>
                   <jbpm:work-item-handlers>
                      <jbpm:work-item-handler name="Event Action" ref="eventActionHandler"/>
                   </jbpm:work-item-handlers>
                  <jbpm:jpa-persistence>
                      <jbpm:transaction-manager ref="JPAtxManager"/>
                      <jbpm:entity-manager-factory ref="entityManagerFactory"/>
                  </jbpm:jpa-persistence>
              </jbpm:configuration>
          </jbpm:ksession>
      
          <bean id="eventActionHandler" class="com.example.events.EventActionHandler">
          </bean>
      </beans>
      

      As you can see I use the same datasource as used in my application .

       

      My persistance file is:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
      <persistence version="1.0"
                   xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
                                       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd
                                       http://java.sun.com/xml/ns/persistence/orm 
                                       http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
                   xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns="http://java.sun.com/xml/ns/persistence">
      
        <persistence-unit name="org.jbpm.persistence.jpa" >
            <provider>org.hibernate.ejb.HibernatePersistence</provider>
            <mapping-file>META-INF/JBPMorm.xml</mapping-file>
            <mapping-file>META-INF/ProcessInstanceInfo.hbm.xml</mapping-file>
      
            <class>org.drools.persistence.info.SessionInfo</class>
            <class>org.jbpm.persistence.processinstance.ProcessInstanceInfo</class>
            <class>org.drools.persistence.info.WorkItemInfo</class>
      
            <properties>
              <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.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
             </properties>
           </persistence-unit>
       </persistence>
      

      When I launch JBOSS I can  see:

       

      19:24:14,006 WARN  [org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager] (eventProcessingTimerFactoryBean) Unable to begin transaction: java.lang.NullPointerException

          at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:696) [spring-tx-3.1.1.RELEASE.jar:3.1.1.RELEASE]

          at org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager.getStatus(DroolsSpringTransactionManager.java:131) [drools-spring-5.4.0.Final.jar:5.4.0.Final]

          at org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager.begin(DroolsSpringTransactionManager.java:45) [drools-spring-5.4.0.Final.jar:5.4.0.Final]

          at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:347) [drools-persistence-jpa-5.4.0.Final.jar:5.4.0.Final]

          at org.drools.command.impl.CommandBasedStatefulKnowledgeSession.startProcess(CommandBasedStatefulKnowledgeSession.java:223) [drools-core-5.4.0.Final.jar:5.4.0.Final]

          at com.example.EventHandlerImpl.EventHandlerImpl.handleEvent(EventHandlerImpl.java:84) [classes:]

          at sun.reflect.GeneratedMethodAccessor658.invoke(Unknown Source) [:1.6.0_29]

          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [rt.jar:1.6.0_29]

          at java.lang.reflect.Method.invoke(Method.java:597) [rt.jar:1.6.0_29]

           ...

       

      19:24:14,065 ERROR [org.drools.persistence.SingleSessionCommandService] (eventProcessingTimerFactoryBean) Could not commit session: java.lang.RuntimeException: Unable to begin transaction

          at org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager.begin(DroolsSpringTransactionManager.java:56) [drools-spring-5.4.0.Final.jar:5.4.0.Final]

          at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:347) [drools-persistence-jpa-5.4.0.Final.jar:5.4.0.Final]

          at org.drools.command.impl.CommandBasedStatefulKnowledgeSession.startProcess(CommandBasedStatefulKnowledgeSession.java:223) [drools-core-5.4.0.Final.jar:5.4.0.Final]

           at om.example.EventHandlerImpl.EventHandlerImpl.handleEvent(EventHandlerImpl.java:84) [classes:]

          ...

       

      Caused by: java.lang.NullPointerException

          at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:696) [spring-tx-3.1.1.RELEASE.jar:3.1.1.RELEASE]

          at org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager.getStatus(DroolsSpringTransactionManager.java:131) [drools-spring-5.4.0.Final.jar:5.4.0.Final]

          at org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager.begin(DroolsSpringTransactionManager.java:45) [drools-spring-5.4.0.Final.jar:5.4.0.Final]

          ... 40 more

       

      19:24:17,761 ERROR [stderr] (eventProcessingTimerFactoryBean) java.lang.RuntimeException: Unable to begin transaction

      19:24:17,765 ERROR [stderr] (eventProcessingTimerFactoryBean)     at org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager.begin(DroolsSpringTransactionManager.java:56)

      19:24:17,767 ERROR [stderr] (eventProcessingTimerFactoryBean)     at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:347)

      19:24:17,769 ERROR [stderr] (eventProcessingTimerFactoryBean)     at org.drools.command.impl.CommandBasedStatefulKnowledgeSession.startProcess(CommandBasedStatefulKnowledgeSession.java:223)

      ..

       

      19:24:17,775 ERROR [stderr] (eventProcessingTimerFactoryBean)     at com.example.EventHandlerImpl.EventHandlerImpl.handleEvent(EventHandlerImpl.java:84) [classes:]

      19:24:17,777 ERROR [stderr] (eventProcessingTimerFactoryBean)     at sun.reflect.GeneratedMethodAccessor658.invoke(Unknown Source)

      19:24:17,779 ERROR [stderr] (eventProcessingTimerFactoryBean)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

      19:24:17,781 ERROR [stderr] (eventProcessingTimerFactoryBean)     at java.lang.reflect.Method.invoke(Method.java:597)

      19:24:17,841 ERROR [stderr] (eventProcessingTimerFactoryBean) Caused by: java.lang.NullPointerException

      19:24:17,842 ERROR [stderr] (eventProcessingTimerFactoryBean)     at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:696)

      19:24:17,844 ERROR [stderr] (eventProcessingTimerFactoryBean)     at org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager.getStatus(DroolsSpringTransactionManager.java:131)

      19:24:17,846 ERROR [stderr] (eventProcessingTimerFactoryBean)     at org.drools.container.spring.beans.persistence.DroolsSpringTransactionManager.begin(DroolsSpringTransactionManager.java:45)

      19:24:17,847 ERROR [stderr] (eventProcessingTimerFactoryBean)     ... 40 more

       

      So what should I do with it? Looks like problems is in two dirfferent transaction managers.  How can I configure in spring to use one TM for both application and JBPM stuff?

      Looks like <jbpm:configuration> has only <jbpm:jpa-persistence> tag inside ? How can I configure my application in right way?