Drools FactException - 已经删除的事实的规则匹配

时间:2016-03-28 23:38:51

标签: equals drools

我遇到了一个奇怪的情况,即被删除的事实被下游规则匹配。这似乎只有在按照这个确切的顺序满足这些条件时才会发生:

  1. 将多个逻辑上不相等的事实(通过equals()方法)插入WM。
  2. 规则更新其中一个事实的属性,使其现在在逻辑上等同于WM中的现有事实。
  3. 其他规则会删除在步骤2中更新的事实。
  4. 不同的规则通过from collect匹配在步骤3中删除的事实。
  5. 当步骤4)中的规则尝试更新或撤消先前删除的事实时,会抛出
  6. org.drools.FactException: Update error: handle not found for object
  7. 关于步骤4)的一个重要注意事项:这个“Ghost Fact”仅在<{1}}中匹配 。如果此阶段的规则只是一个模式,则它与先前删除的事实不匹配。

    对于更具体的示例,我有一个包含成员from collect_uniqueID_type的FruitFact类。 _colorequals()被覆盖:

    hashCode()

    我将2个逻辑上不相等的FruitFacts插入WM:

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!(obj instanceof FruitFact))
            return false;
    
        FruitFact other = (FruitFact) obj;
    
        if (this.getType() == null) {   
            if (other.getType() != null)
                return false;
        } else if (!this.getType().equals(other.getType()))
            return false;
        if (this.getColor() == null) {                  
            if (other.getColor() != null)
                return false;
        } else if (!this.getColor().equals(other.getColor()))
            return false;
    
        return true;
    }
    
    public int hashCode() {
        final int prime = 31;
        int result = 1;
    
        result = prime * result
                + ((this.getType() == null) ? 0 : this.getType().hashCode());
        result = prime * result
                + ((this.getColor() == null) ? 0 : this.getColor().hashCode());
    
        return result;
    }
    

    我的.drl文件如下所示:

    FruitFact f1 = new FruitFact(1, "APPLE", "RED");
    FruitFact f2 = new FruitFact(2, "APPLE", "GREEN");
    wm.insert(f1);
    wm.insert(f2);
    

    上面抛出了一个FactException。 rule "Make non-red apples red" salience 50 when $f: FruitFact(color != "RED") then $f.setColor("RED"); update($f); end rule "retract" salience 30 when $f: FruitFact(id == 2) then retract($f); end rule "arraylist" salience 10 when $fList: ArrayList(size > 0) from collect(FruitFact()) then System.out.println("$fList: " + $fList.toString()); ArrayList $fListCopy = new ArrayList($fList); Iterator it = $fListCopy.iterator(); while (it.hasNext()) { FruitFact $f = (FruitFact) it.next(); retract($f); } end 中的print语句显示ArrayList中唯一的项是已删除的FruitFact(即,id = 2的FruitFact):

    rule "arraylist"

    另一个不寻常的事情是其他FruitFact(id = 1)没有得到规则的匹配。如果我用单一模式规则替换$fList: [FruitFact {_id=2, _type=APPLE, _color=RED}]

    rule "arraylist"

    规则触发一次只收回id = 1的FruitFact,并且不会抛出任何异常,这就是我所期望的。

    我的FruitFact类或我的规则的实现有什么问题吗?为什么这只会发生在“收集”规则而不是单一模式?为什么它只表现出在WM中具有逻辑等价的事实?

    任何见解都将受到赞赏。作为参考,我使用的是Drools 5.5.0.Final。

0 个答案:

没有答案