无法在Drools规则文件中的KIE有状态会话中检索会话对象

无法在Drools规则文件中的KIE有状态会话中检索会话对象,drools,kie,Drools,Kie,在Drools规则文件(drt)中,我将productId和客户名称存储在会话中。我只想在特定客户和产品尚未应用折扣的情况下应用折扣 模板文件的格式(Excel) 下面是drt文件 template header ProductId Quantity Discount package com.main.discount; dialect "java" import java.util.Random; import java.time.LocalDateT

在Drools规则文件(drt)中,我将productId和客户名称存储在会话中。我只想在特定客户和产品尚未应用折扣的情况下应用折扣

模板文件的格式(Excel)

下面是drt文件

 template header
    ProductId
    Quantity
    Discount

    package com.main.discount;

dialect "java"


import java.util.Random;
import java.time.LocalDateTime;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import com.main.discount.Customer;

declare Discount
    lCurrentTime: long
    lCustomerName: String
    lProductId: String
    lExist: boolean
    @timestamp(currentTime)
end

function Discount addDiscount(String productId,String customerName) {
    Discount newRecord = new Discount();
    newRecord.setLCustomerName(customerName);
    newRecord.setLProductId(productId);
    newRecord.setLCurrentTime(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC));
    newRecord.setLExist(true);   
    return newRecord;
}

template "OperationalMeasurement"

rule "Apply_Discount_@{row.rowNumber}"
no-loop
lock-on-active
salience 400
when
  $c: Customer(productId == "@{ProductId}" ,$productId: productId && quantity >= "@{Quantity}" , $quantity: quantity, $customer: CustomerName)
  not (Discount(lProductId == $productId, lCustomerName == $customer))
 then   
    $c.setDiscount("@{Discount}");
    Discount addCondition = addDiscount($productId,$customer);
    insert(addCondition);
    retract($c);
end

end template
下面是调用Initiate Drools Kie会话的代码

  KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
KieSessionConfiguration sessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
sessionConfig.setOption( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) );
try {
    loadRuleTemplate(DATA_FILE, RULE_TEMPLATE_FILE, "Discount", 2, 1);
} catch (IOException errorMsg) {
    log.error(errorMsg.getMessage());       }
InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addPackages(kbuilder.getKnowledgePackages());       
KieSession kieSession =  kbase.newKieSession(sessionConfig, null);
sessionClock = ksession.getSessionClock();
ksession.insert(Customer);
ksession.fireAllRules();
但每次,不忽略条件,即使客户和产品存在记录,它仍然应用折扣,看起来我无法从会话中检索折扣对象。
我使用的是有状态会话。

我猜您遇到的问题与规则中使用的
锁定active
属性有关。激活时的
锁定
很好地避免了无限循环,但它需要付出代价:在调用
fireAllRules()
期间,通过插入或修改事实,无法对该规则进行新的激活

在这里,您可以更好地解释激活的
attibute(以及一些避免使用它的方法)


希望能有所帮助,

@Estebal Aliverti,很抱歉我的代码中没有插入语句。。我有一个insert语句,但它仍然不起作用,我甚至在addDiscount中打印了值,我看到它们正确地被添加,在激活时解除了锁定,仍然发出persistPlease,包括您正在使用的真实代码。您粘贴的代码段似乎有错误。例如,您在规则的RHS中使用了一个从未声明或绑定的
LCCustomerName
变量。条件
lCustomerName==CustomerName
也引用了一个从未绑定的
CustomerName
变量,当您调用
addDiscount()
时,似乎是在以错误的顺序传递参数(您首先传递产品,然后传递客户,但函数以相反的顺序定义它们)。让我困惑的是(假设您尝试删除激活的
锁定
属性),您正在删除规则中的客户(使用
收回
)。应该立即取消所有其他规则的激活。这些是您会话中唯一的规则吗?我有其他规则,当数量小于所需计数时将删除折扣,基本上我正在检查客户和产品是否存在折扣“删除折扣”{row.rowNumber}当$c:Customer(productId==“@{productId}”、$productId:productId&&quantity<“@{quantity}”、$quantity:quantity、$Customer:CustomerName)(折扣(lProductId=$productId,lccustomerName=$Customer))然后$c.setDiscount(“@{Discount}”);Discount addCondition=addDiscount($productId,$Customer);移除(添加条件);收回($c);结束'
  KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
KieSessionConfiguration sessionConfig = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
sessionConfig.setOption( ClockTypeOption.get( ClockType.PSEUDO_CLOCK.getId() ) );
try {
    loadRuleTemplate(DATA_FILE, RULE_TEMPLATE_FILE, "Discount", 2, 1);
} catch (IOException errorMsg) {
    log.error(errorMsg.getMessage());       }
InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addPackages(kbuilder.getKnowledgePackages());       
KieSession kieSession =  kbase.newKieSession(sessionConfig, null);
sessionClock = ksession.getSessionClock();
ksession.insert(Customer);
ksession.fireAllRules();