-1

I do not understand a few parts of this drl code, but I'll just post one question here:

https://github.com/kiegroup/kogito-examples/blob/stable/ruleunit-quarkus-example/src/main/resources/org/kie/kogito/queries/RuleUnitQuery.drl

The full drl code is here:

package org.kie.kogito.queries;
unit LoanUnit;
import org.kie.kogito.queries.LoanApplication;
import org.kie.kogito.queries.AllAmounts;
rule SmallDepositApprove when
    $l: /loanApplications[ applicant.age >= 20, deposit < 1000, amount <= 2000 ]
then
    modify($l) { setApproved(true) };
end
rule SmallDepositReject when
    $l: /loanApplications[ applicant.age >= 20, deposit < 1000, amount > 2000 ]
then
    modify($l) { setApproved(false) };
end
rule LargeDepositApprove when
    $l: /loanApplications[ applicant.age >= 20, deposit >= 1000, amount <= maxAmount ]
then
    modify($l) { setApproved(true) };
end
rule LargeDepositReject when
    $l: /loanApplications[ applicant.age >= 20, deposit >= 1000, amount > maxAmount ]
then
    modify($l) { setApproved(false) };
end
rule NotAdultApplication when
    $l: /loanApplications[ applicant.age < 20 ]
then
    modify($l) { setApproved(false) };
end
query FindApproved
    $l: /loanApplications[ approved ]
end
query FindNotApprovedIdAndAmount
    /loanApplications[ !approved, $id: id, $amount : amount ]
end
rule AllAmounts
when
    accumulate ( $a : /loanApplications ; $sum : sum($a.amount))
then
    allAmounts.add(new AllAmounts($sum));
end
query FindAllApplicationAmounts
    $a : /allAmounts
end

modify($l) { setApproved(true) };

I've seen the use of update in other drl files. What's the difference between modify and update? Are there linked files that are modified?

maxloo
  • 453
  • 2
  • 12

1 Answers1

1

The Drools documentation covers this quite well.

modify is used to change the value of a field within an object in working memory.

update is used to entirely replace an object in working memory with a modified instance.

Both rules trigger a reevaluation of working memory. update, specifically, should be called sparingly, since it triggers a full evaluation of all rules again. (It's like calling 'fire all rules' a second time with new data.)

The reason these actions are important is because regular changes to fields in working memory objects do not cause rule re-evaluation. That is, if you have two rules like this:

rule "Remove invalid houses"
when
  $house: House( forSale == true, price == 0 )
then
  $house.setForSale(false);
end

rule "Schedule inspection for all for-sale houses"
when
  $house: House( forSale == true )
then
  InspectionUtil.schedule($house);
end

... in this case, your second rule would fire even if the first did as well. In this example, we have a House object with a 'for sale' flage (true/false) and a price. If the price is 0, something went wrong with the listing, so we want to remove the 'for sale' indicator. At the same time, we want to schedule all houses for sale for an inspection. When we change the state of the 'for sale' flag to false, that change is not visible to the second "schedule inspection" rule; in order for the change to be visible, you have to use modify:

rule "Remove invalid houses"
when
  $house: House( forSale == true, price == 0 )
then
  modify( $house ) {
    setForSale(false)
  }
end

Now the second rule will not fire, because it will "see" that the house is no longer for sale. I gave a brief overview about how Drools evaluates rule conditions in this other answer if you want a few more details about this and why it works this way.

Roddy of the Frozen Peas
  • 14,380
  • 9
  • 49
  • 99