我是Drools的新手,或者我误解了Drools可以做什么,或者我缺少一些东西。
我有一个简单的事实课
public class MeterReadTO {
private String status = "";
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public boolean isInvalid() {
return status.equals("invalid");
};
}
遵守规则
rule "Rule Invalid"
dialect "mvel"
when
MeterReadTO( isInvalid());
then
System.out.println("Rule Invalid Fired");
end
rule "Rule Not Invalid"
dialect "mvel"
when
not MeterReadTO( isInvalid());
then
System.out.println("Rule Not Invalid Fired");
end
rule "Set Status"
dialect "mvel"
when
$mr: MeterReadTO()
then
System.out.println("Rule Set Status Fires");
modify($mr) {
setStatus("invalid")
}
end
然后我用
运行规则@RunWith(SpringRunner.class)
@SpringBootTest
public class Dependancy {
static KieSession ksession;
Logger logger = LoggerFactory.getLogger(Dependancy.class);
MeterReadTO mr;
@BeforeClass
public static void start() {
KieContainer kieClasspathContainer = KieServices.Factory.get().getKieClasspathContainer();
ksession = kieClasspathContainer.newKieSession("DependancyTest");
}
@Test
public void contextLoadsAndRetrievesData() {
MeterReadTO mr = new MeterReadTO();
mr.setId(50);
ksession.insert(mr);
// when
ksession.fireAllRules();
ksession.dispose();
// Then
System.out.println("After Drools, status is " + mr.getStatus());
}
}
我得到结果
Rule Not Invalid Fired
Rule Set Status Fires
After Drools, status is invalid
通过使用有状态会话,我期望在“规则设置状态”触发后看到“规则无效”触发。如果我将“设置状态”规则从规则列表的底部移到顶部,那么我得到
Rule Set Status Fires
Rule Not Invalid Fired
After Drools, status is invalid
很显然,Drools不了解规则设置状态中的状态更改。我想念什么?
致谢
跟进。
现在我真的很困惑。如果我在规则文件中删除对方法isInvalid()的调用,而改为引用getStatus()方法,则规则现在看起来像
rule "Rule Invalid"
dialect "mvel"
when
MeterReadTO( getStatus() == "ïnvalid");
then
System.out.println("Rule Invalid Fired");
end
rule "Rule Not Invalid"
dialect "mvel"
when
MeterReadTO( getStatus() == "");
then
System.out.println("Rule Not Invalid Fired");
end
rule "Set Status"
dialect "mvel"
when
$mr: MeterReadTO()
then
System.out.println("Rule Set Status Fires");
modify($mr) {
setStatus("ïnvalid")
}
end
然后我得到了期望的输出
Rule Not Invalid Fired
Rule Set Status Fires
Rule Invalid Fired
After Drools, status is ïnvalid
任何人都可以解释发生了什么事吗?
答案 0 :(得分:0)
基本上,正在发生的事情是Drools无法理解,当您更改事实的status
时,方法isInvalid()
的结果会受到影响。
当您修改事实时,Drools将尝试尽量减少对规则的重新评估。就您而言,Drools无法在setStatus()
和isInvalid()
方法之间建立联系。
在第二种情况下,您在规则中使用getStatus()
方法,然后Drools能够进行连接(通过简单的POJO命名约定)。
确保Drools理解setStatus()
和isInvalid()
之间的联系的一种方法是在规则中使用@watch
批注:
rule "Rule Invalid"
dialect "mvel"
when
MeterReadTO( isInvalid()) @watch(status)
then
System.out.println("Rule Invalid Fired");
end
rule "Rule Not Invalid"
dialect "mvel"
when
not MeterReadTO( isInvalid()) @watch(status)
then
System.out.println("Rule Not Invalid Fired");
end
这种方法的问题是您的规则实际上与模型联系在一起。如果您要检查事实是否无效的方式需要修改以包含更多字段,则必须按规则修改@watch
批注。
另一种解决方案是使用@Modifies
批注在模型本身中标记关系:
public class MeterReadTO {
private String status = "";
public String getStatus() {
return status;
}
@Modifies( { "invalid" } )
public void setStatus(String status) {
this.status = status;
}
public boolean isInvalid() {
return status.equals("invalid");
};
}
您可以在Drools' official documentation中找到有关此主题的更多信息。
希望有帮助,