1 2 3 Previous Next 39 Replies Latest reply on Dec 22, 2008 8:19 AM by janvandeklok

    Problem with a decision node in a fork,join construct.

    janvandeklok

      Hello,

      I'm using jbpm 3.3.0. and we noticed a problem with the following process construction:

      a fork that splits into 3 decision nodes, these decision nodes transition to either a task node or directly toi the join.
      Transitions from the decision to the task node are OK, transitions from the decision node directly to the join will throw a StaleObject Exception when trying to update a token for the fork.

      We use Oracle 10 as the database.

      Is it a bug or what ??

      any help is appreciated!

      Jan van de Klok

      Below is the processdefinition used:

      <process-definition xmlns="" name="preConditionCheckUL">
      
       <start-state name="start-state1">
       <transition to="fork1"></transition>
       </start-state>
      
       <task-node name="Controleer student gegevens">
       <description>
       De verzamelde gegevens van student worden gecontroleerd
       </description>
       <task name="Invoer resultaat controle student gegevens">
       <description>
       Taak voor controle juistheid gegevens en invoer resultaat
       </description>
       <assignment pooled-actors="#{actor.groupActorIds}"></assignment>
       </task>
       <transition to="end-state1"></transition>
       </task-node>
      
       <fork name="fork1">
       <transition to="paspoort per post" name="to reg Pasport"></transition>
       <transition to="diploma per post" name="to Registratie ontvangst diploma"></transition>
       <transition to="inschrijfgeld vereist" name="to Registratie ontvangst inschrijfgeld"></transition>
       </fork>
      
       <task-node name="Registratie ontvangst paspoort">
       <description>
       Registratie ontvangst paspoort #{studentStatus.actorId}
       </description>
       <task name="Registreren ontvangst paspoort">
       <description>
       Registreren dat kopie paspoort is ontvangen per post #{studentStatus.actorId}
       </description>
       <assignment pooled-actors="#{studentStatus.pooledActors}"></assignment>
       </task>
       <transition to="join1"></transition>
       </task-node>
      
       <task-node name="Registratie ontvangst diploma">
       <description>
       Registratie ontvangst diploma
       </description>
       <task name="Registreren ontvangst diploma">
       <description>
       Registreren dat kopie diploma is ontvangen per post voor #{studentStatus.actorId}
       </description>
       <assignment pooled-actors="#{studentStatus.pooledActors}"></assignment>
       </task>
       <transition to="join1" name="from reg diploma"></transition>
       </task-node>
      
       <task-node name="Registratie ontvangst inschrijfgeld">
       <description>
       Registratie ontvangst inschrijfgeld voor #{studentStatus.actorId}
       </description>
       <task name="Registreren ontvangst inschrijfgeld">
       <description>
       Registreren dat inschrijfgeld is betaald voor #{studentStatus.actorId}
       </description>
       <assignment pooled-actors="#{studentStatus.pooledActors}"></assignment>
       </task>
       <transition to="join1" name="from inschrijfgeld"></transition>
       </task-node>
      
       <join name="join1">
       <transition to="Controleer student gegevens"></transition>
       </join>
      
       <decision name="paspoort per post">
       <handler class="nl.chronotech.ibis.task.PasportByPostDecision"/>
       <transition to="Registratie ontvangst paspoort" name="byPost"></transition>
       <transition to="join1" name="upload"></transition>
       </decision>
      
       <decision name="diploma per post">
       <handler class="nl.chronotech.ibis.task.DiplomaByPostDecision"/>
       <transition to="Registratie ontvangst diploma" name="byPost"></transition>
       <transition to="join1" name="upload"></transition>
       </decision>
      
       <decision name="inschrijfgeld vereist" expression="#{chosenInstitution eq 'Universiteit Leiden'}">
       <transition to="Registratie ontvangst inschrijfgeld" name="true"></transition>
       <transition to="join1" name="false"></transition>
       </decision>
      
       <end-state name="end-state1">
       </end-state>
      
      </process-definition>


        • 1. Re: Problem with a decision node in a fork,join construct.
          kukeltje

          hhhhhhmmmmmmmmmmmmm.... Deja-vu. This was an issue long ago, but not heard anyone about it since then. Could be that people just not do this very often. What is your isolation level? And could you create a minimal unittest like I described in your other post that demonstrates the problem? Reproducing it here, or at least trying to is easier then for me.

          • 2. Re: Problem with a decision node in a fork,join construct.
            mputz

             

            Deja-vu.

            Isn't https://jira.jboss.org/jira/browse/JBPM-1886 the cause for your deja-vu?

            • 3. Re: Problem with a decision node in a fork,join construct.
              janvandeklok

              Ronald,

              We use transaction level Read-committed as adviced in the documentation.

              <local-tx-datasource>
               <jndi-name>JbpmDS</jndi-name>
               <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
              
              We also tried an XA datasource but that gave the same result.


              • 4. Re: Problem with a decision node in a fork,join construct.
                janvandeklok

                Martin,
                I think it looks like the same problem, will ther be a fix for this soon??

                Jan

                • 5. Re: Problem with a decision node in a fork,join construct.
                  kukeltje

                  hhhhhhhhhhhmmmmmmmmmmmm............. Martin, you are great. Your memory works better than mine ;-)

                  So it was no deja-vu, but a real memory....

                  Jan, so it is a regression. Could you try and the flush to the join node, (re) compile jbpm (or that one class) and test?

                  Index: modules/core/src/main/java/org/jbpm/graph/node/Join.java
                  ===================================================================
                  --- modules/core/src/main/java/org/jbpm/graph/node/Join.java (revision 3339)
                  +++ modules/core/src/main/java/org/jbpm/graph/node/Join.java (working copy)
                  @@ -123,7 +123,9 @@
                   // force version increment by default (LockMode.FORCE)
                   LockMode lockMode = parentLockMode != null ? LockMode.parse(parentLockMode) : LockMode.FORCE;
                   log.debug("acquiring " + lockMode + " lock on " + parentToken);
                  - // lock updates as appropriate, no need to flush here
                  + // Required for Oracle, see https://jira.jboss.org/jira/browse/JBPM-1085
                  + session.flush();
                  + // lock updates as appropriate
                   session.lock(parentToken, lockMode);
                   }
                  
                  


                  • 6. Re: Problem with a decision node in a fork,join construct.
                    janvandeklok

                    Yes, I will do that and let you know about the result.

                    Thanks for your quick response guys!

                    Jan

                    • 7. Re: Problem with a decision node in a fork,join construct.
                      janvandeklok

                      The session.flush() does not seem to make any difference!

                      Changed the code in class Join as follows:

                      109 if (session!=null) {
                       110 LockMode lockMode = LockMode.FORCE;
                       111 if (parentLockMode!=null) {
                       112 lockMode = LockMode.parse(parentLockMode);
                       113 }
                       114 log.debug("forcing version increment on parent token "+parentToken);
                      115 session.flush();
                      116 session.lock(parentToken, lockMode);
                       }


                      and here is the stack trace:


                      2008-12-15 14:06:07,016 ERROR [STDERR] org.hibernate.StaleObjectStateException: Row was updated or deleted by another tr
                      ansaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#367]
                       at org.hibernate.persister.entity.AbstractEntityPersister.forceVersionIncrement(AbstractEntityPersister.java:123
                      5)
                       at org.hibernate.event.def.AbstractLockUpgradeEventListener.upgradeLock(AbstractLockUpgradeEventListener.java:82
                      )
                       at org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:64)
                       at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:584)
                       at org.hibernate.impl.SessionImpl.lock(SessionImpl.java:576)
                       at org.jbpm.graph.node.Join.execute(Join.java:116)
                       at org.jbpm.graph.def.Node.enter(Node.java:319)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at java.lang.reflect.Method.invoke(Method.java:585)
                       at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
                       at org.jbpm.graph.def.Node_$$_javassist_67.enter(Node_$$_javassist_67.java)
                       at org.jbpm.graph.def.Transition.take(Transition.java:151)
                       at org.jbpm.graph.def.Node.leave(Node.java:394)
                       at org.jbpm.graph.exe.ExecutionContext.leaveNode(ExecutionContext.java:136)
                       at org.jbpm.graph.node.Decision.execute(Decision.java:152)
                       at org.jbpm.graph.def.Node.enter(Node.java:319)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at java.lang.reflect.Method.invoke(Method.java:585)
                       at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
                       at org.jbpm.graph.def.Node_$$_javassist_67.enter(Node_$$_javassist_67.java)
                       at org.jbpm.graph.def.Transition.take(Transition.java:151)
                       at org.jbpm.graph.def.Node.leave(Node.java:394)
                       at org.jbpm.graph.def.Node.leave(Node.java:369)
                       at org.jbpm.graph.node.Fork.execute(Fork.java:140)
                       at org.jbpm.graph.def.Node.enter(Node.java:319)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at java.lang.reflect.Method.invoke(Method.java:585)
                       at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
                       at org.jbpm.graph.def.Node_$$_javassist_67.enter(Node_$$_javassist_67.java)
                       at org.jbpm.graph.def.Transition.take(Transition.java:151)
                       at org.jbpm.graph.def.Node.leave(Node.java:394)
                       at org.jbpm.graph.node.StartState.leave(StartState.java:70)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at java.lang.reflect.Method.invoke(Method.java:585)
                       at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
                       at org.jbpm.graph.def.Node_$$_javassist_67.leave(Node_$$_javassist_67.java)
                       at org.jbpm.graph.exe.Token.signal(Token.java:195)
                       at org.jbpm.graph.exe.Token.signal(Token.java:140)
                       at org.jbpm.graph.exe.ProcessInstance.signal(ProcessInstance.java:271)
                       at org.jbpm.graph.node.ProcessState.execute(ProcessState.java:196)
                       at org.jbpm.graph.def.Node.enter(Node.java:319)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at java.lang.reflect.Method.invoke(Method.java:585)
                       at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
                       at org.jbpm.graph.def.Node_$$_javassist_67.enter(Node_$$_javassist_67.java)
                       at org.jbpm.graph.def.Transition.take(Transition.java:151)
                       at org.jbpm.graph.def.Node.leave(Node.java:394)
                       at org.jbpm.graph.node.TaskNode.leave(TaskNode.java:209)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at java.lang.reflect.Method.invoke(Method.java:585)
                       at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
                       at org.jbpm.graph.node.TaskNode_$$_javassist_35.leave(TaskNode_$$_javassist_35.java)
                       at org.jbpm.graph.exe.Token.signal(Token.java:195)
                       at org.jbpm.graph.exe.Token.signal(Token.java:140)
                       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                       at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                       at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                       at java.lang.reflect.Method.invoke(Method.java:585)
                       at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
                       at org.jbpm.graph.exe.Token_$$_javassist_82.signal(Token_$$_javassist_82.java)
                       at org.jbpm.taskmgmt.exe.TaskInstance.end(TaskInstance.java:485)
                       at org.jbpm.taskmgmt.exe.TaskInstance.end(TaskInstance.java:399)
                       at nl.chronotech.ibis.task.TaskManagement.endAllTasks(TaskManagement.java:143)
                       at nl.chronotech.ibis.task.StudentTaskManagement.endAllTasksNow(StudentTaskManagement.java:85)
                      

                      Any other idea's??

                      Jan

                      • 8. Re: Problem with a decision node in a fork,join construct.
                        mputz

                         

                        Your memory works better than mine ;-)

                        I don't know about that, but strangely enough I see roughly the same questions being asked at different channels by different users. Don't know yet why this coincidentally happens, but it does make me look as if I remembered things well ;-)

                        So it was no deja-vu, but a real memory....

                        If you can (still) differentiate, that's a good sign :-)

                        Still trying to get https://jira.jboss.org/jira/browse/JBPM-1772... Tom first said he would reintroduce the flush, but apparently in the end the failing test was fixed/changed, and not the Join?!

                        @Jan, curious to hear about your test results!

                        • 9. Re: Problem with a decision node in a fork,join construct.
                          janvandeklok

                          Martin, Just posted the test result before your last response

                          Jan

                          • 10. Re: Problem with a decision node in a fork,join construct.
                            janvandeklok

                            Martin,
                            The token for which the update fails belongs to the fork and not the join according to the database. Mayby this will help you solving the problem.


                            Jan[/img]

                            • 11. Re: Problem with a decision node in a fork,join construct.
                              kukeltje

                              I know your variables do not behave as expected in 3.2.3 (other topic) but could can you give it a try with 3.2.3 in any way. I need to make sure it is a regression and not something else.

                              • 12. Re: Problem with a decision node in a fork,join construct.
                                kukeltje

                                Oh... yes... can you make the small unit test? I can check here with H2, hsqldb and mysql to validate behaviour against those db's

                                • 13. Re: Problem with a decision node in a fork,join construct.
                                  kukeltje

                                  @Martin,

                                  The fix was for postgress, so I think re-introducing the flush was forgotten

                                  If you can (still) differentiate, that's a good sign :-)

                                  Sorry.... I have no clue what you are talking about

                                  2008-12-15 14:06:07,016 ERROR [STDERR] org.hibernate.StaleObjectStateException: Row was updated or d
                                  eleted by another tr
                                  ansaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#367]
                                   at org.hibernate.persister.entity.AbstractEntityPersister.forceVersionIncrement(AbstractEnti
                                  tyPersister.java:123
                                  5)
                                   at org.hibernate.event.def.AbstractLockUpgradeEventListener.upgradeLock(AbstractLockUpgradeE
                                  ventListener.java:82
                                  )
                                   at org.hibernate.event.def.DefaultLockEventListener.onLock(DefaultLockEventListener.java:64)
                                  
                                   at org.hibernate.impl.SessionImpl.fireLock(SessionImpl.java:584)
                                   at org.hibernate.impl.SessionImpl.lock(SessionImpl.java:576)
                                   at org.jbpm.graph.node.Join.execute(Join.java:116)
                                   at org.jbpm.graph.def.Node.enter(Node.java:319)
                                  


                                  The fork? It is clearly in working in the join... hmmm. These internal workings are still kind of blurry to me. I'm curious what happens if you put async=true on the fork. Should not be needed (imo) but I've seen it make a difference once. Or try async=true on the decisions.

                                  • 14. Re: Problem with a decision node in a fork,join construct.
                                    kukeltje

                                    Can you also try to run with debug on org.jbpm.graph.node.Join? I'm curious to the value of the lockmode. You can also see that in the database on the definition of the specific join node.

                                    1 2 3 Previous Next