1 Reply Latest reply on Sep 28, 2007 6:17 AM by jerome tellier

    Fork/Join JBPM 3.2.2

    Rainer Buss Newbie

      Hello,

      I started to implement my first project with jBPM. We want to implement an automatic process starting
      several jobs in database depending on external events. We do not need user interactions as jBPM offers as tasks.
      We mainly use Nodes and States. The process will run on JBoss 4.2.1 GA and the latest jBPM 3.2.2 and Oracle9i in an EJB3 environment

      As a client interface for deployment, starting, stopping and signaling we use the org.jbpm.command.Command
      classes in a SLSB facade. Since we changed the transaction management to CMT in hibernate configuration and
      the jBPM persistence service to JtaDbPersistenceServiceFactory, as described in http://wiki.jboss.org/wiki/Wiki.jsp?page=Jbpm32UsingCMT
      the process runs well for synchronous processing.
      Additionally we use the following switches

      <service name="persistence" factory="org.jbpm.persistence.jta.JtaDbPersistenceServiceFactory" >
       <field name="sessionFactoryJndiName">
       <string value="java:/WorkflowSessionFactory" />
       </field>
       <field name="isCurrentSessionEnabled"><true /></field>
       <field name="isTransactionEnabled"><false /></field>
      </service>
      

      Important for our process is to be able to start parallel long running jobs and the number of jobs mut be variable.
      In the wiki I found an article by s_telios about an ActionHandler creating dynamically transitions between fork and join
      This solution seems to fit our requirements. I modified it for our purposes and checked it in a test case outside the
      container using the im memory database jdbc:hsqldb:mem:jbpm. was ok.
      Then I switched to oracle and postgres and got the following errors

      ERROR GraphElement : action threw exception: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#3074]
      org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#3074]
      at org.hibernate.persister.entity.AbstractEntityPersister.forceVersionIncrement(AbstractEntityPersister.java:1235)


      I stripped down my test case to a call of a node with a simple action handler between fork and join as shown below:

      The Test Process Definition

      <process-definition name="simple">
      <start-state>
      <transition to="Start Processing VaR Runs" />
      </start-state>
      <fork name="Start Processing VaR Runs">
      <transition name="next" to="Generate RunRequests"></transition>
      </fork>
      <node name="Generate RunRequests">
      <action class=".....actionhandler.SimpleActionHandler" name="SimpleActionHandler">
      <message>Between</message>
      <leaveNode>true</leaveNode>
      </action>
      <transition name="to Join" to="join1" />
      </node>
      <join name="join1">
      <transition name="Preparation Finished" to="end"></transition>
      </join>
      <end-state name="end" />
      </process-definition>
      


      The ActionHandler

      public class SimpleActionHandler implements ActionHandler {
       private static final long serialVersionUID = -1L;
       Boolean leaveNode = true;
       String message = "";
      
       public void execute(ExecutionContext executionContext) throws Exception {
       System.out.println("message: " + message);
       try {
       if (leaveNode) {
       executionContext.leaveNode();
       }
       } finally {
       }
       }
      }
      

      Without database this process is ok. Adding the persistence layer the following error occurs:

      message: Between
      ERROR GraphElement : action threw exception: cannot lock an unsaved transient instance: org.jbpm.graph.exe.Token
      org.hibernate.TransientObjectException: cannot lock an unsaved transient instance: org.jbpm.graph.exe.Token

      I expected that both cases would be handled correctly.

      When I add

      executionContext.getJbpmContext().save(executionContext.getProcessInstance());
      

      in the action handler the test case is ok for the in memory database hsqldb, but postgres delivers:

      ERROR GraphElement : action threw exception: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#3240]
      org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#3240]

      I am rather confused about handling fork/join with database.
      Could anyone give me some advice ?

      ps To keep it short I will not include the original ActionHandler for variable transitions