2012-06-27 49 views
1

情況很簡單。我創建了一個規則文件:Drools:字符串全局變量的奇怪行爲

package org.domain.rules; 
dialect "mvel" 
import eu.ohim.fsp.core.configuration.domain.xsd.Section; 

global java.lang.String sectionName; 

rule "rule 1" 
salience 1000 
when 
    Section($name : nameOfTheSection) 
    eval(sectionName == null) 
then 
    System.out.println("Section: " + $name+ "("+$name.length()+")"); 
    System.out.println("Section Name: " + sectionName + "("+sectionName.length()+")"); 
    System.out.println("Mark Details: " + sectionName.equals(null)); 
end 

和解聘規則之前,我添加了一個有效的coreName節對象和全局:

public void fireInserted(Section section1) { 
    kstateful.insert(section1); 
    kstateful.setGlobal("sectionName", new String("markudetails")); 
    kstateful.fireAllRules(); 
} 

結果是:

Section: markudetails(12) 
Section Name: markudetails(12) 
Mark Details: false 

問題:怎麼可能?在部分爲空並且在那麼部分不爲空!!!

回答

4

全局變量不是知識庫的一部分,而是將某些上下文推入規則執行的單獨通道。在when子句中使用它們是不合適的。您的案例中爲什麼是null的確切原因可能很難追查,因爲規則激活與規則執行完全分離。這個變量可能根本就不在when子句評估時間綁定,但綁定在then子句執行時間。

總結:不要在when子句中使用全局變量,這不是他們的目的。

您的問題有一個簡單的通用解決方案:您可以將配置對象插入到知識中。該對象可以有你想要的「sectionName」屬性,然後你會發現很容易在when中測試。

另外,測試object.equals(null)毫無意義 - 這絕不會產生true。也沒有必要使用new String("markudetails")。請使用"markudetails"

+0

首先:謝謝!但是,考慮在知識中插入多個部分,並且在發佈規則之前,選擇至少要在規則中測試的部分......如何執行此操作?這就是全局變量sectionName的含義。 –

+0

我沒有回覆評論,而是改進了我的回答。 –

+0

是的,我正在考慮這樣做。謝謝! –