There is no functional difference between modify and update. "update" is the
new syntax. See section 3.3.3.1.3 of the expert doc:
https://hudson.jboss.org/hudson/job/drools/lastSuccessfulBuild/artifact/t...
(scroll down a bit)
As for general suggestions to prevent rule re-firing, there are several options. The most
general is "make your conditions the negation of your action." In other words,
the conditions say "the objects are in state A, and not in state B yet" and
state B is what you do to them in the action. So, to modify your example:
rule "Rule1"
when
do : DataObject(FieldA > x, fieldB != value);
then
modify(do.fieldB = value)
end
So something like:
rule "Rule2"
when
do : DataObject(fieldB == value, fieldC != someValue);
then
modify(do.fieldC = someValue)
end
rule "Rule3"
when
do : DataObject(fieldC == someValToMatchForC, do.fieldA != someNewValueForA);
then
modify(do.fieldA = someNewValueForA)
end
So you're always telling the engine to fire the rule if the objects are in some state,
and NOT in the state you're about to put them in.
Another general pattern is to have the objects hold some artificial state (or match them
with an object that holds the artificial state) that restricts rule firing to transitions
in a certain logical path. One simple way to do this is to have a String (or preferably
an Enum) value in the object that informs the rules what artificial state the object is
in.
rule "Rule1"
when
do : DataObject(FieldA > x, state == "StageA");
then
do.setFieldB(value);
do.setStage("StageB");
update(do);
end
So something like:
rule "Rule2"
when
do : DataObject(fieldB == value, state == "StageB");
then
do.setFieldC(someValue)
do.setStage("StageC");
update(do);
end
rule "Rule3"
when
do : DataObject(fieldC == someValToMatchForC, state == "StageC");
then
do.setFieldA(someNewValueForA);
do.setStage("StageD");
update(do);
end
This isn't as restrictive as you might think.
There are also the flow control mechanisms available for rule flow and agenda grouping,
but they don't reach down to the object level. However, mattering on how many
conflicting objects you have in memory at once, they can be quite useful for this purpose
as well. (Basically, you force the entire engine into limited processing states, instead
of individual objects.)
--- On Wed, 9/16/09, Chris Richmond <crichmond(a)referentia.com> wrote:
From: Chris Richmond <crichmond(a)referentia.com>
Subject: Re: [rules-users] determining what field changed
To: "'Rules Users List'" <rules-users(a)lists.jboss.org>
Date: Wednesday, September 16, 2009, 3:52 PM
In general do you have any
suggestions for getting around multiple update
detects being made? In other words I have a rule to
detect if my DataObject
has fieldA > X and if so, then modify fieldB. Then
another rule that checks
if fieldB = value and then updates field C.
So something like:
rule "identify modified DATAOBJECT"
when
do : DataObject(FieldA > x);
then
modify(do.fieldB = value)
end
So something like:
rule "identify modified DATAOBJECT"
when
do : DataObject(fieldB == value);
then
modify(do.fieldC = someValue)
end
rule "identify modified DATAOBJECT"
when
do : DataObject(fieldC ==
someValToMatchForC);
then
modify(do.fieldA = someNewValueForA)
end
But of course this leads to some sort of cross product
execution as each one
is run all over again after another makes a change and
ramps out of control
One question. I have been using modify() and I notice
you had explicit:
do.setN00b(false);
update(do);
What is the difference and will that matter to my
scenario?
Thanks,
Chris
-----Original Message-----
From: rules-users-bounces(a)lists.jboss.org
[mailto:rules-users-bounces@lists.jboss.org]
On Behalf Of Greg Barton
Sent: Wednesday, September 16, 2009 10:14 AM
To: Rules Users List
Subject: Re: [rules-users] determining what field changed
Not really. Without modifying the objects you could
do this outside the
rules using a WorkingMemoryEventListener, which has
objectInserted() and
objectUpdated() methods. Event if you can modify the
DataObject to add an
"I'm a new object" flag, and set it immediately on
insertion, then you could
do differentiate with two rules:
rule "identify new DATAOBJECT"
when
do : DataObject(n00b == true);
then
do.setN00b(false);
update(do);
System.err.println("DataObject assertion detected: "
+ do);
end
rule "identify modified DATAOBJECT"
when
do : DataObject(n00b == false);
then
System.err.println("DataObject modification
detected: " + do);
end
Which would still catch a spurious modification
notification on assert! At
that point the semi-risky alternative is to not call
update() in the
"identify new DATAOBJECT" rule action. That way, the
"identify modified
DATAOBJECT" is not immediately activated, but it would be
activated the next
time update() is called on the object. I say
semi-risky because it's not
often a good idea to put a WM object into a state that the
rete is not aware
of, but in this case it would do what you want.
--- On Wed, 9/16/09, Chris Richmond <crichmond(a)referentia.com>
wrote:
> From: Chris Richmond <crichmond(a)referentia.com>
> Subject: [rules-users] determining what field changed
> To: "'Rules Users List'" <rules-users(a)lists.jboss.org>
> Date: Wednesday, September 16, 2009, 2:41 PM
>
> Is it possible
> to determine what fields from an object
> changed within a rule.
>
> So I am using
> this to determine if any DataObject has
> changed:
>
> //IDENTIFY ANY DATAOBJECT
> CHANGES
>
> rule
> "identify any DATAOBJECT"
> when
> $do :
> DataObject();
> then
> System.err.println("ANY
> DataObject change detected:" + $do);
> End
>
> However this
> also fires when any new DataObject() is
> injected into the system and the rules are fired. I
> would like to be able to
> only have a rule fire when an object is first
> created
>
> Vs. when it is
> modified and is there a way to detect what
> values of an object have changed if I don’t
> explicitly know what fields
> of DataObject changed ahead of time?
>
> Thanks,
> Chris
>
> -----Inline Attachment Follows-----
>
> _______________________________________________
> rules-users mailing list
> rules-users(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/rules-users
>
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users