Question

I am begginer and I am doing a project with Liferay and Drools. I create Drools's rules dinamically with velocity and after I execute it. It works except with the Address, I think it should be because I have some problem with the insert. This is my code:

dialect "java"

rule "Initialize Rules"
    salience 1000
    when
        user : User();
    then
        Serializable value;
        List<Address> params_0 = AddressLocalServiceUtil.getAddresses(user.getCompanyId(), Contact.class.getName(), user.getContactId());
        for(Address param_0 : params_0) {
            insertLogical(param_0);
        }
        List<Address> params_1 = AddressLocalServiceUtil.getAddresses(user.getCompanyId(), Contact.class.getName(), user.getContactId());
        for(Address param_1 : params_1) {
            insertLogical(param_1);
        }
        List<Address> params_2 = AddressLocalServiceUtil.getAddresses(user.getCompanyId(), Contact.class.getName(), user.getContactId());
        for(Address param_2 : params_2) {
            insertLogical(param_2);
        }
        List<Address> params_3 = AddressLocalServiceUtil.getAddresses(user.getCompanyId(), Contact.class.getName(), user.getContactId());
        for(Address param_3 : params_3) {
            insertLogical(param_3);
        }
end

rule "Rule_0"
    when 
        user: User();
        param_0: Address(country.name == "Andorra")
    then
        System.out.println("lalalalalala!");
        classification(user,"Andorra", 7501);
        retract(param_0);   
end

rule "Rule_1"
    when 
        user: User();
        param_1: Address(zip == "00000")
    then
        System.out.println("lalalalalala!");
        classification(user,"ZIP0", 7502);
        retract(param_1);   
end

rule "Rule_2"
    when 
        user: User();
        param_2: Address(city == "Andorra")
    then
        System.out.println("lalalalalala!");
        classification(user,"Andorra", 7503);
        retract(param_2);   
end

rule "Rule_3"
    when 
        user: User();
        param_3: Address(region.name == "Catalonia")
    then
        System.out.println("lalalalalala!");
        classification(user,"Catalonia", 7504);
        retract(param_3);   
end

This is the code that I use to execute it:

String domainName = "User segmentation";
facts.add(new Fact<User> ("user", user));
RulesResourceRetriever rulesResourceRetriever = new RulesResourceRetriever(new StringResourceRetriever(rule), String.valueOf(RulesLanguage.DROOLS_RULE_LANGUAGE));
RulesEngineUtil.update(domainName, rulesResourceRetriever, PortalClassLoaderUtil.getClassLoader());
RulesEngineUtil.execute(domainName, facts, Query.createStandardQuery(), PortalClassLoaderUtil.getClassLoader());

And the user that I pass has one address that is: - country: Andorra - zip: 00000 - city: Andorra

The output must be: lalalalalala! lalalalalala! lalalalalala!

But is only one "lalalalalala!" because the only rule that is validate like true is the first.

I don't know what I am doing wrong. Any idea? Which is the difference between 'insert' and 'insertLogical'? Exist any way to show what elements I have inserted? I do insertLogical because the user can have more than one address, but this is the correct way or is the best.

Thanks.

Was it helpful?

Solution

Facts inserted using insertLogical will remain in the session until the LHS of the rule that iserted it becomes false (or you explicitly retract them using retract()). A better explanation can be found here.

This is what is happening in your situation:

When you insert an Address for Andorra/00000, rules Rule_0, Rule_1 and Rule_2 get activated. When one of this activations gets fired (according to your comments, Rule_0 gets fired first), the RHS of Rule_0 retracts the Address. This will cause the cancellation of the activations for Rule_1 and Rule_2 because there is no longer an Address matching their patterns. More information can be found here.

Hope it helps,

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top