7 Replies Latest reply on Jun 10, 2008 4:36 AM by olivier_debels

    A question to the DecisionNode

      Hi,

      I´ve got a question concerning the DecisionNode. As far as I can read from the documentation the first transition, that resolves to true within a DecisionNode will be used.

      Unfortunately I experienced a different behaviour for my test-process.

      This is part of what I have defined:

       <start-state name="start">
       <transition to="isExceedingOrdered" />
       </start-state>
      
       <decision name="isExceedingOrdered">
       <event type="node-enter">
      <script><expression>System.out.println(executionContext.getNode().getName() + " entered");</expression></script>
       </event>
       <transition name="yes" to="isExceedingBuilt">
       <condition expression="#{contextInstance.variables.orderingState >= 160}" />
       </transition>
       <transition name="no" to="ordered">
       <!-- <condition expression="#{contextInstance.variables.orderingState.ivsCode lt 160}" /> -->
       </transition>
       </decision>
      
       <state name="ordered">
       <transition to="isExceedingOrdered" name="state change"></transition>
       </state>
      
       <decision name="isExceedingBuilt">
       <transition to="built" name="no">
       <condition expression="#{orderingState >= 182}"></condition>
       </transition>
       <transition to="fork" name="yes"></transition>
       </decision>
      
       <state name="built">
       <transition to="isExceedingBuilt" name="state change"></transition>
       </state>
      


      In my first state a set the variable through a java test-class using

      pi.getContextInstance().setVariable(orderingstate, 1);
      


      So as I would say, in the first decision-node (named "isExceedingOrdered") after the starte-node, the first transition should result in false and then use the second transition (named "no"), because it does not have condition, therefor should result in true and then wait in the state "ordered". Unfortunately this works only if I put a condition in the second transition as well (as seen commented in my code above) otherwise it goes directly in the state-node "built". But this is only the case, when I define my transition "no" in "isExceedingBuilt" at first, no matter of what the result of the condition is.

      So this seems a bit strange to me, but possiblly I misunderstood something. So maybe someone can point me to the right direction.

      Thanks
      Thomas

        • 1. Re: A question to the DecisionNode
          kukeltje

          I read somewhere recently in the forum (not sure) that transitionnames have to be unique in some cases. If not, you can get odd behaviour. e.g. that the transition 'no' in your first decision is not pointing to ordered, but to 'built' because of the transition with this same name in your second decision. Can you verify if this is the true?

          • 2. Re: A question to the DecisionNode
            kukeltje

            hmm... this was a recent post about transitionnames within a node.... but still the strange thing here is that a transition is taken that is not existing, so it could still be the cause

            • 3. Re: A question to the DecisionNode

              I will try this and rename my transition and let you know, if that worked.
              But I am right, that the correct bahaviour should be, that the first transition, that results to true, should be taken and - if no condition has been defined - this should automatically result in a true-result.

              Thomas

              • 4. Re: A question to the DecisionNode

                Unfortunately the same behaviour if I use totally different transition names.
                If I do not specify the condition in the second transition, it always uses this transition, although the first transition has already resulted to true.

                Thomas

                • 5. Re: A question to the DecisionNode
                  kukeltje

                  yes, but does it still go to the wrong node?

                  • 6. Re: A question to the DecisionNode

                    it only does, if I do not specify 2 conditions. Otherwise it works flawlessly!

                    • 7. Re: A question to the DecisionNode
                      olivier_debels

                      Well,

                      The reason why it doesn't work is because when you don't add the condition part in your second transition, you end up with a decision node which only contains a single DecisionCondition.

                      When you look into the code of the decision node (the execute method), you will see it loops over all DecisionConditions (in your case only 1!), and checks if it can find one which is true:

                      Iterator iter = decisionConditions.iterator();
                       while (iter.hasNext() && (transition==null)) {
                       DecisionCondition decisionCondition = (DecisionCondition) iter.next();
                       Object result = JbpmExpressionEvaluator.evaluate(decisionCondition.getExpression(), executionContext);
                       if (Boolean.TRUE.equals(result)) {
                       if (transition!=null) {
                       transition.removeConditionEnforcement();
                       }
                       String transitionName = decisionCondition.getTransitionName();
                       transition = getLeavingTransition(transitionName);
                       }
                       }
                      


                      Since this condition fails, it will take the default leaving transition (the first transition.

                      if (transition==null) {
                       transition = getDefaultLeavingTransition();
                       log.debug("decision didn't select transition, taking default "+transition);
                       }
                      


                      What you can do to go around this behaviour:
                      - Make a condition for your second one which is always true (like you did before but you can also use dummy expression's like 1==1).
                      - Move your second condition first, and make sure it always fails (by placing and EMPTY conditiion f.e. ), when all other condition's fail, the default leaving transition will be choosen, and guess this will be the first one, the one with the empty condition element.

                      I would choose the second option.

                      Cheers,

                      Olivier.