2015-04-06 222 views
1

我有一个对象如下:在Drools中执行一个成功的规则后退出6

class License{ 
    private field1; 
    private field2; 
    private boolean active; 
    private String activeMessage; 
    private boolean processed = false; 

    //Getter and setter methods 
} 

我想要做的是,基于对FIELD1和FIELD2的值,我需要设置isActive标志和相应的消息。但是,如果触发了field1或field2的规则,则需要停止规则处理。也就是说,我只需要执行一个成功的规则。

我读了一篇文章,做ksession.fireAllRules(1)将解决这个问题。但是fireAllRules()方法在Drools 6中是不可用的。我也尝试过返回;每条规则末尾的声明。那对我也没有帮助。

最后,我结束了添加一个额外的字段到我的对象称为处理。所以每当我执行任何规则时,我都会将处理过的标志设置为true。如果标志已经设置,那么我不执行任何规则。这是我的规则文件:

rule "Check field1" 
    when 
     $obj : License(getField1() == "abc" && isProcessed() == false) 
    then 
     System.out.println("isProcessed >>>>>> "+$obj.isProcessed()); 
     $obj.setActive(true); 
     $order.setActiveMessage("..."); 
     $order.setProcessed(true); 
end 


rule "Check field2" 
    when 
     $obj : License(getField2() == "def" && isProcessed() == false) 
    then 
     System.out.println("isProcessed >>>>>> "+$obj.isProcessed()); 
     $obj.setActive(true); 
     $order.setActiveMessage("..."); 
     $order.setProcessed(true); 
end 

但是,我看到即使现在我的规则都被解雇了。当我尝试打印isProcessed()的值时,即使仅在isProcessed()为false时才输入规则,它也是如此。

这是我打电话是Drools的引擎:

kieService = KieServices.Factory.get(); 
kContainer = kieService.getKieClasspathContainer(); 
kSession = kContainer.newStatelessKieSession(); 
kSession.execute(licenseObj); 

它不只是2规则,我有很多的规则,通过改变在规则的顺序,以便控制规则执行DRL文件不是一个选项。这里发生了什么?我怎么解决这个问题?我对Drools有点新鲜,所以我可能会在这里错过一些东西。

谢谢。

回答

4

您的问题包含一些错误。

这肯定是不正确的fireAllRules在Drools中6已经消失你可能已经看过的Javadoc索引,找到包org.kie.api.runtime.rule这种方法的四(4!)重载版本在界面StatefulRuleSession

你可以很容易地避免射击的问题刚一出来的两个规则通过将触发约束:

rule "Check field1 and field2" 
when 
    $lic: License(getField1() == "abc" || getField2() == "def") 
    //... 
then 
    $lic.setXxx(...); 
end 

你抱怨,无论你的规则火,尽管在事实上设定processed标志。在这里,你缺少一个的基本点(这在Drools参考手册中有介绍),即每当你改变事实数据时都需要通知引擎。您应该在规则的右侧使用modify

但即使这样也不够好。每当由于某些属性而进行更新时,应该添加一个约束以避免反复运行更新。您可能已经编写:

rule "Check field1 and field2" 
when 
    $lic: License(getField1() == "abc" || getField2() == "def", 
        ! active) 
    //... 
then 
    modify($lic){ setActive(true) } 
end 

你甚至可能在两个不同的规则,每一个领域,只有这些规则会触发一个...

+0

THX写这篇文章,修改($ LIC)做了招。我的印象是事实数据是按顺序传递给规则的,所以更新规则内的数据也会反映到其他规则中。我无法合并规则,因为我在每个规则中执行了许多其他操作。我发布的代码只是一个示例。 – drunkenfist