Drools:使用 Query 获取无状态会话结果
Posted
技术标签:
【中文标题】Drools:使用 Query 获取无状态会话结果【英文标题】:Drools: Get stateless session results using Query 【发布时间】:2020-01-05 05:36:16 【问题描述】:由于它来自官方Drools
documentation,因此可以使用Query
从无状态会话中获取结果。
// Set up a list of commands
List cmds = new ArrayList();
cmds.add( CommandFactory.newSetGlobal( "list1", new ArrayList(), true ) );
cmds.add( CommandFactory.newInsert( new Person( "jon", 102 ), "person" ) );
cmds.add( CommandFactory.newQuery( "Get People" "getPeople" );
// Execute the list
ExecutionResults results =
ksession.execute( CommandFactory.newBatchExecution( cmds ) );
// Retrieve the ArrayList
results.getValue( "list1" );
// Retrieve the inserted Person fact
results.getValue( "person" );
// Retrieve the query as a QueryResults instance.
results.getValue( "Get People" );
在下面的示例中,Get People
是一个流口水 Query
,它基本上返回一个对象或对象列表,形成一个无状态 (!) 会话。
在我的项目中我需要获取一个在无状态Kie session
中创建的对象,所以我创建了一个Query
:
query "getCustomerProfileResponse"
$result: CustomerProfileResponse()
end
CustomerProfileResponse
对象正在RHS
中构造和创建:
insert(customerProfileResponse);
我编写了以下代码以批处理模式执行命令并查询结果CustomerProfileResponse
:
// Creating a batch list
List<Command<?>> commands = new ArrayList<Command<?>>(10);
commands.add(CommandFactory.newInsert(customerProfile));
commands.add(CommandFactory.newQuery(GET_CUSTOMER_PROFILE_RESPONSE,
GET_CUSTOMER_PROFILE_RESPONSE));
// GO!
ExecutionResults results = kSession.execute(CommandFactory.newBatchExecution(commands));
FlatQueryResults queryResults = (FlatQueryResults) results.getValue(GET_CUSTOMER_PROFILE_RESPONSE); // size() is 0!
但是queryResults
返回一个空列表。
我在 Stack Overflow 上搜索类似的问题,发现无法使用批处理模式对 Drools 中的无状态会话运行查询,因为会话在调用 execute()
方法后立即关闭,解决方案是注入一个空的CustomerProfileResponse
对象以及请求中的CustomerProfile
。
有人能解释一下这个问题吗?
【问题讨论】:
经过一些研究后,我还发现如果在实际规则执行之前将“虚拟”或“普通”查询对象作为批处理命令插入会话中,该查询可以正确运行。实际上不确定它是否是一个好的解决方案。 【参考方案1】:在 newInsert 之后和 NewQuery 之前添加 CommandFactory.newFireAllRules() 应该可以解决问题。见http://drools-moved.46999.n3.nabble.com/rules-users-Query-in-stateless-knowledge-session-returns-no-results-td3210735.html
在执行所有命令之前,您的规则不会触发。即隐式 fireAllRules() 是在所有命令都执行后。这意味着将在您的规则触发以插入对象之前调用查询。 您需要在执行查询之前添加 FireAllRules 命令。
【讨论】:
以上是关于Drools:使用 Query 获取无状态会话结果的主要内容,如果未能解决你的问题,请参考以下文章