Drools 7.59版本校验列表长度失败 原有旧版本写法如何调整
根因说明
该问题是Drools 7.45版本引入的非向下兼容默认行为变更导致,与JDK版本无关:
版本更新后,from关键字后跟随集合对象时,默认会迭代集合内的所有元素进行规则匹配,而非旧版本中直接匹配集合对象本身。你原有规则中ArrayList( size >= 3 ) from $books的写法,在新版本中实际是遍历$books内的每一个Book实例,将Book实例与ArrayList类型做匹配,自然无法触发规则,和你补充测试的结果完全吻合。
可行解决方案
方案1:直接在属性约束中校验长度(最推荐)
无需额外调整配置,直接将长度校验合并到Person属性约束中,写法简洁且性能最优:
rule "Person has 3 or more existing checked out books" when BookEvent( type == BookEventType.BORROW ) Person( $books: checkedOutBooks, checkedOutBooks.size >= 3 ) then result.setSuccess(false); result.setReason("User has already checked out 3 books"); end
方案2:全局恢复旧版本from行为
如果存量规则中大量使用原有写法,逐个改造成本较高,可以通过配置将from逻辑恢复为旧版本逻辑:
- 启动时设置系统参数:
System.setProperty("drools.fromIteratesOnCollections", "false");
- 或在
kmodule.xml的kbase配置中添加属性:
<kbase name="defaultKBase" packages="*"> <property name="drools.fromIteratesOnCollections" value="false"/> </kbase>
配置生效后你原有的规则写法即可正常触发。
方案3:显式用collect匹配集合
如果不想修改全局配置,也可以通过collect显式对集合进行封装后匹配:
rule "Person has 3 or more existing checked out books" when BookEvent( type == BookEventType.BORROW ) Person( $books: checkedOutBooks ) $bookList: ArrayList( size >=3 ) from collect( $element from $books ) then result.setSuccess(false); result.setReason("User has already checked out 3 books"); end
内容的提问来源于stack exchange,提问作者Roddy of the Frozen Peas
相关产品推荐
相关产品推荐

