为什么这个规则 运行 不止一次?
Why does this rule run more than once?
我创建了这条规则:
rule "Product PRODUCT_A is not available from other insurers as INSURER_A"
when
$p : Policy(insurer.name != "INSURER_A", product.name == "PRODUCT_A", $v : validations)
not (Validation(level == ValidationLevel.ERROR) from $v)
then
log.info("Matching rule for {} with validations: {}", $p.getInsurer().getName(), $p.getValidations());
$p.addValidation(new Validation(ValidationLevel.ERROR, "This insurance is not available for " + $p.getInsurer().getName()));
end
当我注入 4 个保单对象时,全部用于 PRODUCT_A,一个的保险公司名称为 INSURER_A,另外三个具有其他名称,日志记录显示:
DroolsController - Matching rule for INSURER_B with validations: []
DroolsController - Matching rule for INSURER_C with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B)]
DroolsController - Matching rule for INSURER_D with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_C)]
DroolsController - Matching rule for INSURER_B with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_D), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_C)]
DroolsController - Matching rule for INSURER_C with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_D), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_C)]
DroolsController - Matching rule for INSURER_D with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_D), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_C)]
我觉得这很奇怪。我期望在每个策略(INSURER_A 除外)上都会有一个验证对象。但是,验证对象似乎已添加到所有策略对象中。当我阅读结果时,每个验证对象都被添加到所有策略中,即使是 PRODUCT_A 策略。
我的规则有什么问题?我如何更改规则以使其按预期运行?
这与定义的规则无关。
您输入的政策事实是克隆对象。然而,这是一个浅克隆而不是深度克隆。因此策略对象中的验证列表仍然指向克隆中的相同验证列表。
对一个对象添加验证时,因为其他对象引用了同一个列表,所以它们也会被添加到其他对象。
Drools 首先创建一个所有条件都为真的议程。当你修改一个对象时,它发现它被改变了,就会相应地更新议程。但是,策略对象没有改变,所以规则是 运行 即使在引用列表中有新的验证。
如果您不想多次执行规则,那么您可以 'retract' 从记忆中获取事实。它将避免多次执行规则。
我创建了这条规则:
rule "Product PRODUCT_A is not available from other insurers as INSURER_A"
when
$p : Policy(insurer.name != "INSURER_A", product.name == "PRODUCT_A", $v : validations)
not (Validation(level == ValidationLevel.ERROR) from $v)
then
log.info("Matching rule for {} with validations: {}", $p.getInsurer().getName(), $p.getValidations());
$p.addValidation(new Validation(ValidationLevel.ERROR, "This insurance is not available for " + $p.getInsurer().getName()));
end
当我注入 4 个保单对象时,全部用于 PRODUCT_A,一个的保险公司名称为 INSURER_A,另外三个具有其他名称,日志记录显示:
DroolsController - Matching rule for INSURER_B with validations: []
DroolsController - Matching rule for INSURER_C with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B)]
DroolsController - Matching rule for INSURER_D with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_C)]
DroolsController - Matching rule for INSURER_B with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_D), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_C)]
DroolsController - Matching rule for INSURER_C with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_D), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_C)]
DroolsController - Matching rule for INSURER_D with validations: [Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_D), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_B), Validation(id=0, level=ERROR, description=This insurance is not available for INSURER_C)]
我觉得这很奇怪。我期望在每个策略(INSURER_A 除外)上都会有一个验证对象。但是,验证对象似乎已添加到所有策略对象中。当我阅读结果时,每个验证对象都被添加到所有策略中,即使是 PRODUCT_A 策略。
我的规则有什么问题?我如何更改规则以使其按预期运行?
这与定义的规则无关。
您输入的政策事实是克隆对象。然而,这是一个浅克隆而不是深度克隆。因此策略对象中的验证列表仍然指向克隆中的相同验证列表。
对一个对象添加验证时,因为其他对象引用了同一个列表,所以它们也会被添加到其他对象。
Drools 首先创建一个所有条件都为真的议程。当你修改一个对象时,它发现它被改变了,就会相应地更新议程。但是,策略对象没有改变,所以规则是 运行 即使在引用列表中有新的验证。
如果您不想多次执行规则,那么您可以 'retract' 从记忆中获取事实。它将避免多次执行规则。