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.

Était-ce utile?

La 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,

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top