Naved Alam
Naved Alam

Reputation: 827

Drools conditional element `not` firing RHS even if corresponding fact is present

I have drools rule something like this

rule "some name"
when
  not Fact(
      field() == "something",
      group() in ("groupA", "groupB", "groupC"),
      isAllowed == true)
then
  // do something
end

I have following fact in the system

Fact{field=something, group=groupA, isAllowed=false)
Fact{field=something, group=groupB, isAllowed=false)
Fact{field=something, group=groupC, isAllowed=true)

Now my understanding about not conditional element is that there must be none of matching fact in the working memory for rule to get trigger. However, in my test, rules are getting trigger irrespective of whether there is a fact with isAllowed present in the working memory.

Is my understanding of not correct? If not, what would be the best way to model a rule which fires when there is no matching fact in the working memory?

Thank you!

Upvotes: 0

Views: 86

Answers (1)

Roddy of the Frozen Peas
Roddy of the Frozen Peas

Reputation: 15180

The way not works, is that it won't trigger if the given fact matches all of the criteria. You indicate you have 3 facts which I'm going to label A, B, and C so I can reference them easier:

A: Fact{field=something, group=groupA, isAllowed=false)
B: Fact{field=something, group=groupB, isAllowed=false)
C: Fact{field=something, group=groupC, isAllowed=true)

Fact A does not match the pattern -- field and group conditions are satisfied, but isAllowed is not. Fact B also does not match the pattern for the same reason. Fact C does match the pattern -- field, group, and isAllowed conditions are all satisfied.

If you fire your rules with everything in working memory, it works as you'd expect:

rule "Example"
when
  not( Fact( field == "something", group in ("groupA", "groupB", "groupC"), isAllowed == true) )
then
  System.out.println("Rule fired");
end
KieSession session = ... // omitted for brevity
session.insert(new Fact("something", "groupA", false));
session.insert(new Fact("something", "groupB", false));
session.insert(new Fact("something", "groupC", true)); // *
session.fireAllRules();

... you will see that there is nothing printed as a result.

If you omit the final fact, where I've added the // * comment in the example above, you'll see the rule fire and the message get printed.


If you're seeing different behavior, you're doing something wrong. Either you're firing your rules without all the facts present, or your facts don't actually look like you think they do, or the way you're checking the data isn't correct.

But, as stated in your question, not works like you think it does. It triggers when there is no fact in working memory that matches the criteria declared.

Upvotes: 1

Related Questions