当前位置: 首页 > 知识库问答 >
问题:

Drools规则-多个问题(停止执行,停止执行的条件)不起作用

艾凯捷
2023-03-14

我使用Drools6.1.0.final和一个无状态会话来激发所有规则。

在我的.drl文件中有以下两个简单的规则。

rule "Null Check"
    when
        $paymentHolder : PaymentHolder(pmtRequest.requestDetails == null 
        || pmtRequest.requestDetails.paymentData == null
        || pmtRequest.requestDetails.paymentData.accountDetails == null
        || pmtRequest.requestDetails.paymentData.payments == null
        || pmtRequest.requestDetails.paymentData.payments.payment == null
        || pmtRequest.requestDetails.paymentData.payments.payment.get(0).tenderDetails == null
        || pmtRequest.requestDetails.paymentData.payments.payment.get(0).tenderDetails.paymentCardDetails == null
        || pmtRequest.requestDetails.paymentData.payments.payment.get(0).tenderDetails.paymentCardDetails.authorizationInfo == null)
    then
        System.out.println("Some Manadatory data is null ");
        // populate error code and error message
        List<ErrorHolder> errors = $paymentHolder.getErrors();
        ErrorHolder erroHolder = new ErrorHolder();
        errors.add(erroHolder);
      erroHolder.setErrorCode(com.wdpr.payment.exception.ErrorCode.MANDATORY_DATA_MISSING);
        // drools.halt();
       // kcontext.getKieRuntime().halt();        
end

rule "Amount is -ve"
    when
        
        $paymentHolder : PaymentHolder(errors.size() == 0)
    $paymentHolder(pmtRequest.getRequestDetails()!.getPaymentData().getPayments().getPayment().get(0).getAmount().getAmount() < 0)
    then
        //System.out.println(paymentHolder.getProcessId());
        System.out.println("Amount is -ve");
        //throw new com.wdpr.payment.exception.PaymentPlatformException(com.wdpr.payment.exception.ErrorCode.DATA_RANGE_INVALID, "Data Range Invalid - Amount", null);
end

我想这样做:如果第一个规则为true,则不执行任何其他规则,并从。drl文件退出。

我试着如下:

>

  • 试图在第一个规则的Then块中抛出运行时异常,但由于NullPointerException的原因,它仍然会在第二个规则中失败。

    添加了drools.halt()和kcontext.getkieruntime().halt(),但没有工作,仍在执行下一条规则。

    Exception in thread "main" java.lang.RuntimeException: Error while creating KieBase[Message [id=1, level=ERROR, path=com/my/payment/rules/validation.drl, line=40, column=0
       text=[ERR 102] Line 40:53 mismatched input '!.' in rule "Amount is -ve"], Message [id=2, level=ERROR, path=com/my/payment/rules/validation.drl, line=0, column=0
       text=Parser returned a null Package]]
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.getKieBase(KieContainerImpl.java:349)
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.newStatelessKieSession(KieContainerImpl.java:540)
        at org.drools.compiler.kie.builder.impl.KieContainerImpl.newStatelessKieSession(KieContainerImpl.java:528)
        at com.my.payment.workflow.DroolsRuleProcessor.runRules(DroolsRuleProcessor.java:58)
        at com.my.payment.workflow.DroolsRuleProcessor.main(DroolsRuleProcessor.java:81)
    

    我的java代码片段

    // some code
    
    final StatelessKieSession kSession = this.kContainer.newStatelessKieSession(rulesSession);
    
             // provide the necessary data and execute rules.
             kSession.execute(paymentHolder);
    

    注意:我不想使用显着和激活组

  • 共有1个答案

    夏长卿
    2023-03-14

    解决方案很简单(尽管可能不讨好你)。若要避免在访问包含对象的字段的约束计算中出现NPE,请确保字段不为null,或者将针对null的测试与访问结合起来。

    // (#1) either:
    class PmtRequest {
        // guarantee non-null requestDetails
        List<rRequestDetail> requestDetails = new ArrayList<>(); 
    
    
    // (#2) or:
    when
    $paymentHolder: PaymentHolder(errors.size() == 0,
                    pmtRequest != null &&
                    pmtRequest.getRequestDetails() ... )
    then ...
    

    对于深度嵌套的约束,这越来越不方便,这就是为什么建议不要编写这样的访问,而是将包含的对象作为事实插入,或者在顶层对象中添加方法来访问包含的对象。

    还有另一个选择(#3):在规则执行中使用两个会话。新的PaymentHolder事实必须通过只包含nun-null测试的第一个会话,然后才能插入到第二个会话中。

     类似资料:
    • 问题内容: 我已经编写了一个包含循环的“ Hangman”游戏,不断询问用户字母,直到他们解决单词或耗尽生命。奇怪的是,在满足条件时循环不会停止。 这是包含循环的游戏逻辑的实现: 可变结果是从方法中获取返回值。这是实现。 难道是我返回导致循环不断循环的值的方式吗?我这样声明了这些值: 问题答案: 逻辑上,根据德摩根定律, 是相同的 这永远是一个真实的表达。 条件可能应该是 当应用与上述相同的法律时

    • 问题内容: 我有以下代码: 在发生某些事件之后,我应该停止在的方法中声明的操作,该方法实现。 我怎样才能做到这一点?我无法关闭执行器,只能撤消我的定期任务。我可以用吗?如果可以的话,请告诉我它将如何工作。 问题答案: 使用。该是你的任务的处理。您需要取消此任务,它将不再执行。 实际上,是签名,并将其与参数一起使用将导致当前正在运行的执行线程被调用中断。如果线程在阻塞的可中断调用(例如)中等待,则会

    • 问题内容: 我查看了Javadoc,但找不到与此相关的信息。 如果该方法中的代码告诉我这样做,我希望应用程序停止执行该方法。 如果那句话令人困惑,这就是我想在代码中执行的操作: 因此,如果布尔值为true,则该方法必须停止执行其他代码。 这只是一个例子。我还有其他方法可以完成我在应用程序中要完成的工作,但是如果可能的话,肯定会有所帮助。 问题答案: 做就是了: 只写是多余的(例如,这样就不会误写)

    • 但问题是整个作业被多次执行,事实上它根本没有停止。我必须强制停止工作执行。我在表中只有2行。我认为这是因为xml中定义了commit-interval,但是如果commit-interval=10,作业将执行10次以上 根据我的理解,当我运行xml文件(意味着我只运行作业一次)时,它调用读取器一次,将数据保存在运行时内存(作业存储库)中,调用项处理器一次(我使用列表),并且整个列表一次插入

    • 我通过创建固定数量的线程来使用执行器服务来进行HTTP GET数据检索。 当Tomcat停止时,我们会出现以下错误: 严重:web应用程序[/viewer]似乎已启动名为[ThreadExecutor_51616156]的线程,但未能停止该线程。这很可能会造成内存泄漏。 这是真的吗?在没有这些服务错误的情况下,如何正确停止tomcat。