drools rule flow

12,268

Solution 1

When you modify working memory facts, you need to tell Drools that the data has changed so it can re-evaluate all relevant rules.

Drools evaluates facts before firing any matched rules. If you have a dog with age = 0 and baby = false, both your rules will be activated. When your is my dog a baby? rule is fired, it doesn't change the fact that when Drools evaluated the baby dog rule, the myDog.isBaby() == false condition was true.

To inform Drools that you have modified some fact, use the update() knowledge helper method. Keep in mind that Drools associates fact handles to a specific object. If a rule references MyData, and you want that rule to be re-evaluated when the MyData.myDog object has changed, you'll need to use update() on the MyData object; just doing update() on your Dog object, will not cause the baby dog rule to be re-evaluated.

Try changing your is my dog a baby? rule to the following:

rule "is my dog a baby?"
    ruleflow-group "dog"
    salience 10
    when 
        dog : Dog(age < 1, baby == false)
        myData : MyData(myDog == dog)
    then
        dog.setIsBaby(true);
        update(dog);
        update(myData);
    end

Solution 2

You need to do

then 
    dog.setIsBaby(true);
    update( dog ) 

on your first rule and rewrite the when of your second rule like

when
    dog :    Dog( isBaby == false)
    myData : MyData( myDog == dog)

The rule has to be written in this way, so drools can automatically detect which rules it has to run again after a fact changes.

Every time you change a fact in the rules engine, you need to tell the working memory that you've changed it with update.

I haven't used drools since version 4, but I assume that this still applies.

Solution 3

Yes you should update both the dog and the map. Cheers

Share:
12,268

Related videos on Youtube

Ricky Bobby
Author by

Ricky Bobby

Updated on June 04, 2022

Comments

  • Ricky Bobby
    Ricky Bobby almost 2 years

    I'm having a strange issue with drools :

    I have the following rules :

    rule "is my dog a baby?"
      ruleflow-group "dog"
      salience 10
      when 
         dog : Dog(age <1 )
      then 
         dog.setIsBaby(true);
    end
    
    
    rule "baby dog"
        ruleflow-group "dog"
        salience 9
        when
            myData : MyData( myDog.isBaby() == false)
        then
            System.out.println(myData.getMyDog().getIsBaby());
    end
    

    I insert in my session myData and myData.getMyDog(), where myData.getMyDog.isBaby==false

    The first rule is fired and my dog is set to be a baby. Then the second one is fired, and even it prints true .(even if the condition was to be false)

    And when I test after firing all rules , myDog in myData is set to be a baby .

    What am I doing wrong here ? Why does the second rule is fired ? is the problem in the session (stateful in my case) ?

    I think that I need to say that I modify myData:myDog somewhere ,but I am not sure where .

    Hope my question is clear, if not tell me.

  • Ricky Bobby
    Ricky Bobby over 12 years
    Thx a lot I'm going to try that
  • Ricky Bobby
    Ricky Bobby over 12 years
    Thx a lot I'm going to try that