【问题标题】:Drools rules not getting firedDrools 规则不会被解雇
【发布时间】:2012-09-03 08:27:46
【问题描述】:

我对 Drools 很陌生,可能正在做一些非常愚蠢的事情。问题是由于某种原因我的 Drools 规则没有被解雇。使用的 drools 版本是 5.4

如果有帮助,当我切换回StatelessKnowledgeSession 并使用 execute 方法来触发规则时,规则就会触发。但是,我需要使用AgendaFilter 来过滤规则,并且我知道StatelessKnowledgeSession 尚不支持议程过滤器。作为第一步,我只是将会话切换到StatefulKnowledgeSession,插入事实并触发所有规则。

不得不谦虚地说,在过去的几天里,我为此感到头疼。太糟糕了,文档对流口水不太友好(我参考了官方文档和用户指南。

下面引用了我从规则文件加载知识的规则验证器代码和 Spring 工厂 bean。我个人认为FactoryBean 没有任何问题。任何指针都会有很大帮助。

RuleValidator.java

StatefulKnowledgeSession ksession = knowledgeBase.newStatefulKnowledgeSession();
ksession.setGlobal("validationReport", validationReport);
ksession.setGlobal("simpleCache", simpleCache);
ksession.setGlobal("ruleValidator", this);

ksession.insert(allClientDetails); //this is a list of ClientDetails objects (facts)
ksession.fireAllRules();
ksession.dispose();

return validationReport;

KnowledgeBaseFactory.java

import java.io.IOException;
import java.util.Map;

import org.apache.log4j.Logger;
import org.drools.KnowledgeBase;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.Resource;
import org.drools.io.ResourceFactory;
import org.springframework.beans.factory.FactoryBean;


public class KnowledgeBaseFactory implements FactoryBean<KnowledgeBase> {

    private static Logger logger=Logger.getLogger(KnowledgeBaseFactory.class);

    private KnowledgeBase knowledgeBase;

    public KnowledgeBaseFactory(Map<String,ResourceType> resourceMap) throws IOException {
        logger.debug("Resource Map : "+resourceMap);
        final KnowledgeBuilder knowledgeBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        for (Map.Entry<String, ResourceType> eachRuleResource:resourceMap.entrySet()){
            knowledgeBuilder.add(ResourceFactory.newClassPathResource(eachRuleResource.getKey()),eachRuleResource.getValue());

        }

        if (knowledgeBuilder.hasErrors()){
            logger.error(knowledgeBuilder.getErrors().toString());
            throw new RuntimeException(knowledgeBuilder.getErrors().toString());
        }
        knowledgeBase = knowledgeBuilder.newKnowledgeBase();
        knowledgeBase.addKnowledgePackages(knowledgeBuilder.getKnowledgePackages());
    }

    @Override
    public KnowledgeBase getObject() throws Exception {
        return knowledgeBase;
    }

    @Override
    public Class<?> getObjectType() {
        return knowledgeBase.getClass();
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

【问题讨论】:

  • 所以你只是改变了行“StatefulKnowledgeSession ksession = KnowledgeBase.newStatefulKnowledgeSession();”从 StatelessKnowledgeSession 到有状态的,它不再起作用了?对吗?
  • 是的。那是对的。而且由于我从StatelessKnowledgeSessionexecute 方法切换到StatefulKnowledgeSession 中的fireAllRules 方法,所以我不得不使用ksession.insert(allClientDetails);insert。但是,是的,这就是那里所做的所有更改。
  • 如果不知道那里有什么规则和事实是什么样子,很难说什么可能是错的。我会回到基础,开始看看你是否可以得到一个简单的规则来触发插入事实,然后从那里开始构建..
  • @Nim 同意。我退后一步,重新开始。当我发现有用的东西时,让我回来发帖。

标签: java drools


【解决方案1】:

感谢@Nim 的提示

终于想通了。我应该正确阅读 API 文档。
显然,我在StatelessKnowledgeSession 中使用了Iterable 重载execute 方法,该方法遍历了我的所有事实并将规则应用于每个事实。

但是,对于StatefulKnowledgeSession,我应该事先进行迭代并一一插入事实。然后,我可以解雇规则。

StatefulKnowledgeSession 中没有 insert(Iterable) 方法的任何原因。

【讨论】:

    猜你喜欢
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2016-04-05
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    相关资源
    最近更新 更多