Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drools rule condition - check if attribute is null

Tags:

java

drools

I have a fairly simple case where I want to check in my rule condition whether an attribute is not null.

rule "only do action if attribute is not null"
when
    $fact : Fact(attribute!=null, $attribute : attribute)
then
    rulesLogger.debug("Rule fires = " + $attribute);
end

I have tracked this through in debug. A Fact is being inserted with the attribute as null but the rule still fires. The console output is as follows.

Rule fires = null

If I change the condition to attribute==null then the rule doesn't fire. So it seems to be doing the exact opposite to what I would expect.

We do have a workaround for this using a function but it's a bit ugly and I can't figure out why it doesn't work in the first place.

function Boolean attributeExists(Fact fact)
{
    if(fact.getAttribute() == null)
    {
        return Boolean.FALSE;
    }
    else
    {
        return Boolean.TRUE;
    }
}

rule "only do action if attribute is not null"
when
    $fact : Fact($attribute : attribute)
    Boolean(booleanValue == true) from attributeExists($fact)
then
    rulesLogger.debug("Rule fires = " + $attribute);
end

EDIT 1

The drools version is 5.3.0.

The fact is loaded via another rule using from and a service method call. I can't see that the fact is invalid because it prints as I would expect to the console and also the manual workaround with a function works as expected. It's a strange one.

EDIT 2

I've found a better workaround. If I access the attribute using the getter method then the rule behaves as expected. This looks much better than having to write an extra function but it would still be nice to know why this isn't working when using the property name.

rule "only do action if attribute is not null"
when
    $fact : Fact(getAttribute()!=null, $attribute : attribute)
then
    rulesLogger.debug("Rule fires = " + $attribute);
end

The Fact class is just a boring POJO. It has no superclass other than Object and implements no interfaces. It's not a JPA entity or anything where there might be a proxy or lazy loading.

like image 621
Ben Thurley Avatar asked Oct 28 '22 21:10

Ben Thurley


1 Answers

Try some of these. I'm not sure whether D was possible with 5.3.

rule "only do action if attribute is not null"
when
  Fact($att: attribute != null)             /* A */
  Fact($att: attribute, eval($att != null)) /* B */
  Fact($att: attribute, attribute != null)  /* C */
  Fact($att: attribute, $att != null)       /* D */
then
  rulesLogger.debug("Rule fires = " + $attribute);
end

An upgrade is highly recommended. 5.5.0 might be an option where no code breaks but failures like this one are avoided.

like image 159
laune Avatar answered Nov 01 '22 01:11

laune