Search code examples
javadroolsrules

How to avoid loops in Drools without using NO-LOOP attribute?


Is there any possible way to avoid looping without using NO-LOOP attribute of Drools(Like I have heard we can achieve this by using the not(!) operator on objects but am unable to find out.)

The problem is NO-LOOP attribute can't be used(as that is the requirement) so refer to the rule below and tell is it possible to avoid looping.

TestClass.java

public class TestClass{
     private String name;
     private int age;

// Few other variables
// their getters and setters

}

Rules

rule "abc"
    when 
        $obj : TestClass(name=="test", age != 20)
    then 
        TestClass $obj2 = new TestClass();
        $obj2.setName("test");
        $obj2.setAge(30);
        insert($obj2);
end

Solution

  • Not sure why some folks are so afraid of no-loop. It exists for a perfectly good reason. i.e. It instructs the engine to not re-evaluate a rule if the reason for that re-evaluation is due to modifications or insertions in that rule.

    However, you can do it manually through your own logic. Just insert an appropriate fact and match on it not existing.

    declare IsTested
        name: String
    end
    
    rule "abc"
    when 
        $obj : TestClass($name: name=="test", age != 20)
        not IsTested(name == $name)
    then 
        TestClass $obj2 = new TestClass();
        $obj2.setName("test");
        $obj2.setAge(30);
        insert($obj2);
        insert(new IsTested($name));
    end
    

    A while back, Esteban Aliverti wrote a blog post on common patterns for avoiding infinite loops in Drools. It's worth a read.