在Drools

时间:2017-07-26 13:21:34

标签: drools rule

我们一直在编写一条规则,用于更改在同一天重复的结算项目的状态,并且每天只需付费一次。所有项目的状态均为2或3开头。

如果在状态为2或3的项目上检测到重复代码,则该项目将获得状态4,并且工作记忆中的项目将更新。

当实现单元测试时,我们可以看到结果是正确的,但是一旦我们从工作内存中检索对象,项目的顺序似乎已经变得非常随机。 这是正常的,为什么会发生? (显然,异常,如果有的话,可以通过再次重新排序列表来纠正。)

以这种方式插入对象:

Iterator<Object> it = objects.iterator();
while (it.hasNext()) {
    sessionStatefull.insert(it.next());
}

通过向KieSession添加记录器来实现其日志:

public static KieSession getStatefulKnowledgeSessionWithCallback(KieContainer kieContainer, String sessionName) {
   KieSession kieSession = null;
    try {
        kieSession = getStatefulKnowledgeSession(kieContainer, sessionName);
        kieSession.addEventListener(new RuleRuntimeEventListener() {
            OutputDisplay outputDisplay = new OutputDisplay();

            @Override
            public void objectInserted(ObjectInsertedEvent objectInsertedEvent) {
                outputDisplay.showText("getStatefulKnowledgeSessionWithCallback.INSERT", objectInsertedEvent.getObject().toString());               
            }

输入始终相同:

Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169800, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169801, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169802, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169803, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169804, units=1.0, code=6358]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169805, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169806, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169807, units=1.0, code=6385]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169808, units=1.0, code=6005]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169809, units=1.0, code=6225]

以这种方式获得输出:

    List<Object> list = new ArrayList<Object>((Collection<Object>) sessionStatefull.getObjects());

使用迭代器获取其日志:

    Iterator<Object> it2 = list.iterator();
    while (it2.hasNext()) {
        Object object = it2.next();
        outputDisplay.showText("Result: ", object.toString());
    }

打印输出似乎总是有一个随机顺序:

示例1:

Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169809, units=1.0, code=6225]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169801, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169800, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169803, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169802, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169807, units=1.0, code=6385]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169805, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169804, units=1.0, code=6358]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169806, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169808, units=1.0, code=6005]

示例2:

Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169804, units=1.0, code=6358]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169803, units=1.0, code=2   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169806, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169805, units=1.0, code=6007]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=4, id=150107315169801, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169808, units=1.0, code=6005]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169807, units=1.0, code=6385]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169800, units=1.0, code=1   ]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169809, units=1.0, code=6225]
Item [date=Tue Jul 25 00:00:00 CEST 2017, status=2, id=150107315169802, units=1.0, code=2   ]

logger类的定义如下:

public class OutputDisplay {

    public void showText(String source, String text) {
        try {
            long time = System.currentTimeMillis();
            Date date = new Date(time);
            writeLog(time+" "+date.toString()+" A message from "+source+": "+text);

        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

writeLog 打开一个文件并添加该行。我们还没有注意到一些更复杂的日志(即logback ......)。

1 个答案:

答案 0 :(得分:0)

Drools不会在内部保持插入对象的顺序。您使用的getObjects()方法通过返回Collection而不是List来说明这一点。

记录器按顺序显示对象,因为只要新对象插入工作内存就会调用它。

如果您想为对象提供一些逻辑顺序,我建议您在从工作记忆中检索它们后对它们进行排序。

希望它有所帮助,