82.7.3. Rule unit identity conflicts


In rule unit execution scenarios with guarded rule units, a rule can guard multiple rule units and at the same time a rule unit can be guarded and then activated by multiple rules. For these two-way guarding scenarios, rule units must have a clearly defined identity to avoid identity conflicts.

By default, the identity of a rule unit is the rule unit class name and is treated as a singleton class by the RuleUnitExecutor. This identification behavior is encoded in the getUnitIdentity() default method of the RuleUnit interface:

Default identity method in the RuleUnit interface

default Identity getUnitIdentity() {
    return new Identity( getClass() );
}

In some cases, you may need to override this default identification behavior to avoid conflicting identities between rule units.

For example, the following RuleUnit class contains a DataSource definition that accepts any kind of object:

Example Unit0 rule unit class

public class Unit0 implements RuleUnit {
    private DataSource<Object> input;

    public DataSource<Object> getInput() {
        return input;
    }
}

This rule unit contains the following DRL rule that guards another rule unit based on two conditions (in OOPath notation):

Example GuardAgeCheck DRL rule in the rule unit

package org.mypackage.myunit
unit Unit0

rule GuardAgeCheck
  when
    $i: /input#Integer
    $s: /input#String
  then
    drools.guard( new AgeCheckUnit($i) );
    drools.guard( new AgeCheckUnit($s.length()) );
end

The guarded AgeCheckUnit rule unit verifies the age of a set of persons. The AgeCheckUnit contains a DataSource definition of the persons to check, a minAge variable that it verifies against, and a List for gathering the results:

Example AgeCheckUnit rule unit

public class AgeCheckUnit implements RuleUnit {
    private final int minAge;
    private DataSource<Person> persons;
    private List<String> results;

    public AgeCheckUnit( int minAge ) {
        this.minAge = minAge;
    }

    public DataSource<Person> getPersons() {
        return persons;
    }

    public int getMinAge() {
        return minAge;
    }

    public List<String> getResults() {
        return results;
    }
}

The AgeCheckUnit rule unit contains the following DRL rule that performs the verification of the persons in the data source:

Example CheckAge DRL rule in the rule unit

package org.mypackage.myunit
unit AgeCheckUnit

rule CheckAge
  when
    $p : /persons{ age > minAge }
  then
    results.add($p.getName() + ">" + minAge);
end

This example creates a RuleUnitExecutor class, binds the class to the KIE base that contains these two rule units, and creates the two DataSource definitions for the same rule units:

Example executor and data source definitions

RuleUnitExecutor executor = RuleUnitExecutor.create().bind( kbase );

DataSource<Object> input = executor.newDataSource( "input" );
DataSource<Person> persons = executor.newDataSource( "persons",
                                                     new Person( "John", 42 ),
                                                     new Person( "Sally", 4 ) );

List<String> results = new ArrayList<>();
executor.bindVariable( "results", results );

You can now insert some objects into the input data source and execute the Unit0 rule unit:

Example rule unit execution with inserted objects

ds.insert("test");
ds.insert(3);
ds.insert(4);
executor.run(Unit0.class);

Example results list from the execution

[Sally>3, John>3]

In this example, the rule unit named AgeCheckUnit is considered a singleton class and then executed only once, with the minAge variable set to 3. Both the String "test" and the Integer 4 inserted into the input data source can also trigger a second execution with the minAge variable set to 4. However, the second execution does not occur because another rule unit with the same identity has already been evaluated.

To resolve this rule unit identity conflict, override the getUnitIdentity() method in the AgeCheckUnit class to include also the minAge variable in the rule unit identity:

Modified AgeCheckUnit rule unit to override the getUnitIdentity() method

public class AgeCheckUnit implements RuleUnit {

    ...

    @Override
    public Identity getUnitIdentity() {
        return new Identity(getClass(), minAge);
    }
}

With this override in place, the previous example rule unit execution produces the following output:

Example results list from executing the modified rule unit

[John>4, Sally>3, John>3]

The rule units with minAge set to 3 and 4 are now considered two different rule units and both are executed.

Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

Red Hat ドキュメントについて

Legal Notice

Theme

© 2026 Red Hat
トップに戻る