2015-04-06 84 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