I am trying hands on at the Drools rule engine , I am quite a beginner.
I have the following rules in place in a single rule file:
rule "A stand alone rule"
salience 2
no-loop
when
$account : Account()
Account($account.balance>100)
then
System.out.println("balance>100");
System.out.println($account.getBalance());
System.out.println($account.getCustomer().getName());
end
rule "A second Rule"
salience 1
no-loop
when
$account : Account()
Account($account.balance<100)
then
System.out.println("balance<100");
System.out.println($account.getBalance());
System.out.println($account.getCustomer().getName());
end
In the StatefulKnowledgeSession I am passing TWO accounts , one with balance 15000 another with balance 15 ,
Account account=new Account(7l,15000l);
Account account1=new Account(5l,15l);
Customer customer = new Customer("Samrat", 28, "Sector51", account);
Customer customer1 = new Customer("Alexi", 28, "Sector50", account1);
account.setCustomer(customer);
account1.setCustomer(customer1);
session.insert(account);
session.insert(account1);
session.fireAllRules();
According to me the expected result should be that each rule should be fired only once and the corresponding object should be printed.
But the result I am getting is :
balance>100
15000
Samrat
balance>100
15000
Samrat
balance<100
15
Alexi
balance<100
15
Alexi
I am not able to understand why each rule is running twice ????
Using multiple patterns (and not specifying any relation between them) will create a full Cartesian product (just like a select on multiple tables without a join clause). So, the rule:
rule A
when
Account()
Account()
then
...
end
will be activated N^2 times for N objects of type Account. One solution could be to use the magic field 'this' to specify that the second account is the same as the first one:
rule A
when
$a: Account()
Account(this == $a)
then
...
end
But, going back to your example, I think you don't even need to use 2 different patterns. You could rewrite your rules as following:
rule "A stand alone rule"
salience 2
no-loop
when
$account: Account(balance>100)
then
System.out.println("balance>100");
System.out.println($account.getBalance());
System.out.println($account.getCustomer().getName());
end
rule "A second Rule"
salience 1
no-loop
when
$account: Account(balance<100)
then
System.out.println("balance<100");
System.out.println($account.getBalance());
System.out.println($account.getCustomer().getName());
end
Hope it helps,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With