16.5.6. Property-change settings and listeners for fact types

By default, the decision engine does not re-evaluate all fact patterns for fact types each time a rule is triggered, but instead reacts only to modified properties that are constrained or bound inside a given pattern. For example, if a rule calls modify() as part of the rule actions but the action does not generate new data in the KIE base, the decision engine does not automatically re-evaluate all fact patterns because no data was modified. This property reactivity behavior prevents unwanted recursions in the KIE base and results in more efficient rule evaluation. This behavior also means that you do not always need to use the no-loop rule attribute to avoid infinite recursion.

You can modify or disable this property reactivity behavior with the following KnowledgeBuilderConfiguration options, and then use a property-change setting in your Java class or DRL files to fine-tune property reactivity as needed:

  • ALWAYS: (Default) All types are property reactive, but you can disable property reactivity for a specific type by using the @classReactive property-change setting.
  • ALLOWED: No types are property reactive, but you can enable property reactivity for a specific type by using the @propertyReactive property-change setting.
  • DISABLED: No types are property reactive. All property-change listeners are ignored.

Example property reactivity setting in KnowledgeBuilderConfiguration

KnowledgeBuilderConfiguration config = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
config.setOption(PropertySpecificOption.ALLOWED);
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(config);

Alternatively, you can update the drools.propertySpecific system property in the standalone.xml file of your Red Hat Decision Manager distribution:

Example property reactivity setting in system properties

<system-properties>
  ...
  <property name="drools.propertySpecific" value="ALLOWED"/>
  ...
</system-properties>

The decision engine supports the following property-change settings and listeners for fact classes or declared DRL fact types:

@classReactive

If property reactivity is set to ALWAYS in the decision engine (all types are property reactive), this tag disables the default property reactivity behavior for a specific Java class or a declared DRL fact type. You can use this tag if you want the decision engine to re-evaluate all fact patterns for the specified fact type each time the rule is triggered, instead of reacting only to modified properties that are constrained or bound inside a given pattern.

Example: Disable default property reactivity in a DRL type declaration

declare Person
  @classReactive
    firstName : String
    lastName : String
end

Example: Disable default property reactivity in a Java class

@classReactive
public static class Person {
    private String firstName;
    private String lastName;
}

@propertyReactive

If property reactivity is set to ALLOWED in the decision engine (no types are property reactive unless specified), this tag enables property reactivity for a specific Java class or a declared DRL fact type. You can use this tag if you want the decision engine to react only to modified properties that are constrained or bound inside a given pattern for the specified fact type, instead of re-evaluating all fact patterns for the fact each time the rule is triggered.

Example: Enable property reactivity in a DRL type declaration (when reactivity is disabled globally)

declare Person
  @propertyReactive
    firstName : String
    lastName : String
end

Example: Enable property reactivity in a Java class (when reactivity is disabled globally)

@propertyReactive
public static class Person {
    private String firstName;
    private String lastName;
}

@watch

This tag enables property reactivity for additional properties that you specify in-line in fact patterns in DRL rules. This tag is supported only if property reactivity is set to ALWAYS in the decision engine, or if property reactivity is set to ALLOWED and the relevant fact type uses the @propertyReactive tag. You can use this tag in DRL rules to add or exclude specific properties in fact property reactivity logic.

Default parameter: None

Supported parameters: Property name, * (all), ! (not), !* (no properties)

<factPattern> @watch ( <property> )

Example: Enable or disable property reactivity in fact patterns

// Listens for changes in both `firstName` (inferred) and `lastName`:
Person(firstName == $expectedFirstName) @watch( lastName )

// Listens for changes in all properties of the `Person` fact:
Person(firstName == $expectedFirstName) @watch( * )

// Listens for changes in `lastName` and explicitly excludes changes in `firstName`:
Person(firstName == $expectedFirstName) @watch( lastName, !firstName )

// Listens for changes in all properties of the `Person` fact except `age`:
Person(firstName == $expectedFirstName) @watch( *, !age )

// Excludes changes in all properties of the `Person` fact (equivalent to using `@classReactivity` tag):
Person(firstName == $expectedFirstName) @watch( !* )

The decision engine generates a compilation error if you use the @watch tag for properties in a fact type that uses the @classReactive tag (disables property reactivity) or when property reactivity is set to ALLOWED in the decision engine and the relevant fact type does not use the @propertyReactive tag. Compilation errors also arise if you duplicate properties in listener annotations, such as @watch( firstName, ! firstName ).

@propertyChangeSupport

For facts that implement support for property changes as defined in the JavaBeans Specification, this tag enables the decision engine to monitor changes in the fact properties.

Example: Declare property change support in JavaBeans object

declare Person
    @propertyChangeSupport
end