2015-12-23 64 views
1

我在使用Drools时遇到问题。 我尝试从嵌套成员更新属性。更新似乎有效,但when子句不考虑它。Drools更新嵌套成员属性

我有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到时子句匹配,则更新计数器(从0到1)的值。所以Obj2不应该与where子句匹配。 但事实上,确实如此,即使显示是如我所料:

obj1 0 
obj2 1 

有人可以解释我什么我做错了?

回答

1

对于事实集合中的变化,Drools规则引擎的所有反应都需要通过使用右手边语言的扩展之一来通知。您需要为修改的事实对象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