Drools全局变量更新异常求助:getGlobal调用返回null
问题原因与解决方案
核心问题
你遇到的getGlobal("count")返回null,本质是未在KieSession中预先注册全局变量。Drools规则中通过kcontext.getKieRuntime().setGlobal()设置的全局变量,若未提前在Session中初始化,只会存在于规则执行的上下文,外部无法通过kieSession.getGlobal()获取到。
修复步骤
- 在Java代码中预先初始化全局变量:在调用
fireAllRules()之前,先注册全局变量并赋予初始值:
// 初始化全局变量count,初始值设为0.0 kieSession.setGlobal("count", 0.0); kieSession.insert(csaResponseRootDTO); kieSession.fireAllRules(); System.out.println(kieSession.getGlobal("count")); // 现在能获取到规则中设置的值 kieSession.dispose();
- 优化DRL规则的分支写法(可选,提升代码可读性):
你当前使用的do[yes]/then[yes]分支语法可改用标准if-else逻辑,避免分支匹配歧义:
rule "Calculate the score" when $p : DTO() $section : SectionsDTO(sectionName == "XX") from $p.sectionsList $subSection : SubSectionsDTO(subSectionName == "YY") from $section.subSectionsList $question : QuestionDTO(questionId == "ZZ") from $subSection.questionsList $questionOption : OptionsDTO(selected == true, $key : key) from $question.questionnaireOptions then double calc; if($key == "yes"){ calc = ConfigContextInitiator.checkBalances(reportConfig, $section.sectionName, $subSection.subSectionName, $question.questionId, $key); System.out.println("yes分支计算值:" + calc); } else if($key == "no"){ calc = ConfigContextInitiator.checkBalances(reportConfig, $section.sectionName, $subSection.subSectionName, $question.questionId, $key); System.out.println("no分支计算值:" + calc); } else { calc = 0.0; // 处理未匹配的键值情况 } kcontext.getKieRuntime().setGlobal("count", calc); end
多规则更新全局变量的可运行示例
以下是完整的多规则更新同一全局变量的示例,包含Java和DRL代码:
Java代码
import org.kie.api.KieServices; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; public class DroolsGlobalDemo { public static void main(String[] args) { // 初始化Kie容器 KieServices kieServices = KieServices.Factory.get(); KieContainer kieContainer = kieServices.getKieClasspathContainer(); KieSession kieSession = kieContainer.newKieSession(); // 预先初始化全局变量totalScore Double totalScore = 0.0; kieSession.setGlobal("totalScore", totalScore); // 插入事实对象 UserAnswer answer1 = new UserAnswer("Q1", "yes"); UserAnswer answer2 = new UserAnswer("Q2", "no"); kieSession.insert(answer1); kieSession.insert(answer2); // 执行所有规则 kieSession.fireAllRules(); // 获取更新后的全局变量 System.out.println("最终总分:" + kieSession.getGlobal("totalScore")); kieSession.dispose(); } // 定义事实类:用户答题结果 public static class UserAnswer { private String questionId; private String answer; public UserAnswer(String questionId, String answer) { this.questionId = questionId; this.answer = answer; } // 必须提供getter方法供规则匹配使用 public String getQuestionId() { return questionId; } public String getAnswer() { return answer; } } }
DRL规则文件(resources/rules/scoreRules.drl)
package com.example.rules; import com.example.DroolsGlobalDemo.UserAnswer; // 规则1:处理Q1的yes答案,加10分 rule "Rule1 - Q1 Yes" when UserAnswer(questionId == "Q1", answer == "yes") then Double current = (Double)kcontext.getKieRuntime().getGlobal("totalScore"); kcontext.getKieRuntime().setGlobal("totalScore", current + 10.0); System.out.println("规则1执行:总分更新为" + (current + 10.0)); end // 规则2:处理Q2的no答案,加5分 rule "Rule2 - Q2 No" when UserAnswer(questionId == "Q2", answer == "no") then Double current = (Double)kcontext.getKieRuntime().getGlobal("totalScore"); kcontext.getKieRuntime().setGlobal("totalScore", current + 5.0); System.out.println("规则2执行:总分更新为" + (current + 5.0)); end
内容的提问来源于stack exchange,提问作者contacttosoumya83
相关产品推荐
相关产品推荐

