我在使用Drools时遇到了问题。 我尝试从嵌套成员更新属性。更新似乎有效,但是when子句不考虑它。
我有2个Obj对象,共享同一个Cpt对象。
Cpt cpt = new Cpt();
Obj obj1 = new Obj("obj1");
obj1.setComposant("R2");
obj1.counter = cpt;
Obj obj2 = new Obj("obj2");
obj2.setComposant("R2");
obj2.counter = cpt;
kSession.insert(obj2);
kSession.insert(obj1);
我的规则定义为:
rule "R2"
when
m : Obj(composant == "R2" && counter.value == 0)
then
System.out.println(m.getName() + " " + m.getCounter().getValue());
m.getCounter().increment();
end
我希望Obj1匹配when子句,然后更新计数器的值(从0到1)。所以Obj2不应该与where子句匹配。 但事实上,即使显示器符合我的预期,它确实如此:
obj1 0
obj2 1
有人可以解释一下我做错了什么吗?
答案 0 :(得分:1)
Drools Rule Engine对事实变更的所有反应都需要使用右手边语言的扩展之一进行通知。您需要为修改后的事实对象f调用update(f),或者您可以使用modify(f){...}语句。
但是......通过事实A的引用更改包含的对象X并告诉引擎事实A已被修改,这不会使它看到事实B也引用了X,也已经改变了。
这是您应该重新考虑您的设计的地方。是否真的有必要通过A和B的引用共享X?或者:如何使X成为事实并更新它?后者可能意味着您必须重写规则,使Obj和Cpt之间的关系在左侧可见。但是,根据我的经验,通常比使用某些复杂机制将更新通知从一些联合包含对象传播到其父对象更好。
修改“使关系可见”的含义由以下规则显示:
rule "R2"
when
Obj(composant == "R2", $counter: counter )
$c: Cpt( this == $counter, value == 0)
then
modify( $c ){ increment() }
end