Value changed

images/download/attachments/201668199/image-2025-4-9_12-46-29-version-1-modificationdate-1744195588787-api-v2.png

The Value changed compare type typically aims to check in the context of an Entity property rule whether the volatile data state of an entity present as a reference object differs from the associated Original entity with respect to a certain check value configuration.

The check value configuration here refers to the value configuration in the Entity property rule that uses the Value changed compare type. In the screenshot (above), the check value configuration is an Object property resolver that accesses a (fictitious) 'Check value' field of an unspecific type 'Entity'.


images/s/-95e2zf/9012/8yg2g7/_/images/icons/emoticons/warning.svg CAUTIONimages/s/-95e2zf/9012/8yg2g7/_/images/icons/emoticons/warning.svg In the client context (Client workflow), the Value changed resolver is effectively useless, because there the Original entity is always the volatile state of the entity in the execution context (see Original entity), so the return value is always false .


In the simplest case, the check value configuration determines a 'simple value' (e.g. a String from a text field) whose state in context may or may not match the value determined from the Original entity (hereafter referred to as the original value).

If the check value configuration refers to a 'complex value', i.e. a data object with multiple values in fields, then the return values for the reference object and the Original entity are compared according to the logic of the Equals comparison, taking into account the selection for the Deep compare option.

For the evaluation of 'complex values' (data objects with fields) the following cases have to be distinguished:

  • If the class of the check value provides specific comparison logic, this determines the criteria according to which the check value and original value are considered to match or change.

    • In the context of entities, this particularly concerns the values of attributes of different types that may be assigned to an entity at the header or line item level.

    • Attribute values of certain attribute types are compared directly 'by content' even without selecting the Deep compare option. All 'useful data' of the attribute value are included, except for the index field, which affects only Plural attributes.

    • For attribute entities, i.e. the entries in the attributes list field of the respective attribute owner (with one attribute value each in the value field), on the other hand, no specific comparison function takes effect (see next point).

  • If the check value class does not provide specific comparison logic (e.g. for a complete line item), the Deep compare option must be activated so that the Value changed comparison provides meaningful results.

    • Without a content check, two data objects, which at best are clones with identical content, would always be considered different, i.e. 'changed'.

    • The 'deep comparison' requested by the Deep compare option may be applied recursively to all levels of a nested data object and may be correspondingly CPU-intensive depending on its complexity. Therefore, the Deep compare object contents option should be used 'sparingly' with regard to runtime behaviour.

Configuration

The Value changed comparison type requires an entity to be the reference object in the context of the parent Entity property rule.

IMPORTANT◄ If there is no entity as the reference object, the Entity property rule is considered 'failed' (false). The check value configuration is not then evaluated.

If the Value changed compare type is selected for an Entity property rule, only one value configuration is displayed, referred to here as the check value configuration.

The Deep compare option in the compare type configuration is switched off (OFF) by default.

images/download/attachments/201668199/image-2025-4-9_12-47-7-version-1-modificationdate-1744195626975-api-v2.png

In the example on the right, an Object property value resolver has been added via the context menu of the check value configuration, which accesses the 'owner' field (ownerId).

This field is present for each entity. It identifies a company account as the 'owner' of the entity via its ID and therefore contains a Long value. The Deep compare option therefore remains switched off (OFF) for the comparison.

images/download/attachments/201668199/image-2025-4-9_12-48-7-version-1-modificationdate-1744195686954-api-v2.png

The following configuration for an Entity property rule is functionally completely equivalent:

images/download/attachments/201668199/image-2025-4-9_12-48-47-version-1-modificationdate-1744195726897-api-v2.png

The Value changed compare type simplifies the configuration, because on the one hand the Original entity value resolver (top right) does not have to be used explicitly and on the other hand the redundant value configuration in the compare value (bottom right) is omitted. IIn this very simple example, the benefit is still clear, but if a more complex Chained resolver is required in the check value configuration, the Value changed compare type not only saves effort but also allows for a more compact representation and avoids the risk of unintended deviations when creating and adjusting redundant value resolver chains.

The Deep compare object contents option should be used only if the comparison of complex data objects requires it:

images/download/attachments/201668199/image-2025-4-9_12-49-20-version-1-modificationdate-1744195760550-api-v2.png

By default, the Deep compare option is switched off (OFF). Then the Value changed comparison for complex data objects is passed only if their class (e.g. an attribute value class) defines a specific comparison logic (see above).

Otherwise, a complex data object (e.g. a specific position of an entity) always appears as 'changed' because accessing the Original entity always returns a clone as the original value, which – even if all contained values match – is not identical to the check value.

images/download/attachments/201668199/image-2025-4-9_12-49-38-version-1-modificationdate-1744195777597-api-v2.png

If the Deep compare option is switched on, then all characteristics (such as fields, attributes, etc.) of the data objects resolved via the check value configuration are compared (recursively if necessary) to determine whether the same object is described in terms of content and form. However, the check does not take into account whether the object is technically the same. This 'deep comparison' is generally more time-consuming than the simple comparison of the identity of two objects performed by default (see above).

The images/s/-95e2zf/9012/8yg2g7/_/images/icons/emoticons/warning.svg icon (see screenshot) appears when the option is turned on to indicate that comparing object contents can adversely affect performance.

Examples

Simple use case: Sending an e-mail when a user is deactivated

Event handling for the 'Update' event (see Common action event) is used to check in the context of a user account (see Users) whether the 'Active' status is withdrawn from the user account in question when the transaction is completed. In this case, a notification is to be sent by e-mail.

Configuration:

'Update' is selected as the only Triggering event for the event handling shown on the right.


The Validating rule consists of three conditions in a common AND Junction:

NOTE◄ Which value for 'Active' was present in the Original entity is not explicitly checked here. For a Booelan field, only true and null can technically be considered as original values other than false. Since the default value for the 'Active' field in the user account is defined as false, null can only be the original value if the user account has not yet been saved, so that no Original entity exists. This case is excluded in our event handling, because here only the 'Update' event and not also 'Create' is provided as a Triggering event.


The only Action on passed rule here is a E-Mail to notify the concerned user.

images/download/attachments/201668199/image-2025-4-9_12-52-7-version-1-modificationdate-1744195927667-api-v2.png

Komplexerer Anwendungsfall: Änderungen an E-Mail-Kommunikationsinformationen registrieren

Beim Speichern eines bereits existierenden Benutzerkontos (→ Common action event: "Ändern") soll festgestellt werden, ob Änderungen an den Kommunikationsinformationen für den Communication type "E-Mail" (EMAIL) vorgenommen wurden.

Laufzeitbeispiel:

images/download/attachments/201668199/image-2025-4-9_12-53-55-version-1-modificationdate-1744196034790-api-v2.png

  • Die Eigenschaften Typ, Kontext und Wert stellen die "Nutzlast" einer Kommunikationsinformation dar.

  • Jede "Zeile" im Screenshot repräsentiert eine Instanz für diesen pluralen Attributtyp des Adresse-Objekts (s. Addresses), der nicht-typisiert ist, obwohl er ein Typ-Feld beinhaltet.

Konfiguration:

Die folgende Regel-Konfiguration zielt darauf ab, Änderungen an Kommunikationsinformationen in der Adresse eines Benutzers festzustellen, die den Typ "E-Mail" (EMAIL) betreffen.

Die im Screenshot rechts abgebildete UND-Junction für die Prüfende Regel einer Ereignisbehandlung, die auf das Ereignis "Ändern" (Common action event) reagiert, enthält zwei Regeln:

  • Die initiale Check type stellt fest, ob ein "Benutzer" als Bezugsobjekt vorliegt. Nur dann wird die zweite Regel ausgewertet.

  • Die Entity property rule verwendet den Value changed-Vergleichstyp mit der Option Objektinhalte vergleichen (s. "WICHTIG" unten) und folgender Wertauflöserkette für den Prüfwert:

    • Ein Object property-Wertauflöser greift auf das Feld address zu.

    • Der verkettete Plural attributes (Resolver) liefert eine Liste aller Instanzen für den Attributtyp "Kommunikationsinformation".

    • Der verkettete Rule list resolver liefert - da die Option Alle Werte als Liste ausgewählt ist - eine Liste aller Kommunikationsinformationen in der Benutzer-Adresse, für die die unterhalb definierte Entity property rule erfüllt ist:

      • Die Entity property rule prüft per Equals-Vergleichstyp, ob das Feld "Typ" (communicationType) mit dem statisch definierten Vergleichswert "E-Mail" (EMAIL) übereinstimmt.


images/download/attachments/201668199/image-2025-4-9_12-55-34-version-1-modificationdate-1744196133962-api-v2.png

WICHTIG◄ Die Option Objektinhalte vergleichen muss ausgewählt sein (AN), sonst gilt die Regel unabhängig von Änderungen an E-Mail-Kommunikationsinformationen immer als bestanden. Der Grund dafür ist, dass der Plural attributes (Resolver)-Wertauflöser bei jedem Aufruf immer eine neue Liste mit Attributwerten erzeugt. Der Value changed-Vergleichstyp impliziert zwei Aufrufe der Prüfwert-Konfiguration. Also werden zwei Listen verglichen, die ohne die Option Objektinhalte vergleichen auch dann als nicht übereinstimmend gelten, wenn sie dieselben Attribute auflisten und diese keine Wertänderungen beinhalten. Nur der aufwändigere Vergleich der Objektinhalte - hier: der "inhaltliche Vergleich" der Listen - erkennt die Listen als "gleichwertig", solange keines der Attribute geändert wurde.

Allerdings ist die obige Prüflogik (mit der Option Objektinhalte vergleichen) auch noch nicht perfekt in ihrem Urteilsvermögen bzgl. der Änderungen. Die Schwachstelle ist dabei das orderIndex-Feld, das jeder "Kommunikationsinformation" (bzw. jeder Instanz des pluralen Attributs) eine Reihenfolgeposition zuordnet. Der Plural attributes (Resolver)-Wertauflöser liefert die Attributinstanzen in der Reihenfolge aufsteigender orderIndex-Werte, was hilfreich für den Abgleich mit dem implizit herangezogenen Original entity ist. Allerdings nur, solange sich am orderIndex der betreffenden Instanzen nicht geändert hat:

  • Wenn im obigen Laufzeitbeispiel einer der Einträge für "Mobil"-Nummern an einer Listenposition vor dem E-Mail-Eintrag (hier: am Ende der Liste) entfernt wird, sollte das eigentlich im Sinne der Aufgabenstellung nicht als Änderung in Bezug auf die "E-Mail"-Adresse gewertet werden.

  • Allerdings ändert sich der orderIndex-Wert des "E-Mail"-Eintrags (von 2 auf 1) da er zwar immer noch am Ende der Liste steht, nun aber nur noch einen Vorgänger hat.

  • Auch das Hinzufügen einer "Telefon"-Eintrags oberhalb des "E-Mail"-Eintrags würde irrtümlich als E-Mail-Änderung interpretiert, außer er würde dafür ein anderer entfern, sodass der "E-Mail"-Eintrag seine absolute Reihenfolgeposition beibehält.

Alternativkonfiguration:

Der Screenshot rechts zeigt, wie die Wertauflöserkette für den Prüfwert erweitert werden kann, sodass der Value changed-Vergleichstyp nur die relevanten Eigenschaften von Kommunikationsinformationen für "E-Mail"-Einträge berücksichtigt:

  • Als Nachfolger für den Rule list resolver wird ein Collect values-Wertauflöser hinzugefügt.

  • Als Wert zum Sammeln wird ein Create instance with values-Wertauflöser verwendet, der alle relevanten Eigenschaften der betreffenden Kommunikationsinformation auf Felder eines erzeugten Client-Objekts abbildet, die eindeutig (aber willkürlich) benannt werden können. Im konkreten Fall betrifft das genau zwei Felder.


ANMERKUNG◄ Die Methode einer selektiven "Transkription" kompletter Einträge mag radikal erscheinen. Für ein einfaches Objekt wie die Kommunikationsinformation ist sie aber "gangbar" und auch recht effizient. Im konkreten Fall könnte man, da es um String-Felder geht, auch mit einer Concat strings im Collect values-Wertauflöser zum Ziel kommen. Allerdings muss man dann ein Trennzeichen "reservieren" (ggf. auch eine Trennzeichenfolge), das per Konvention in beiden Felder nicht verwendet werden darf.

Natürlich gibt es zahllose weitere Lösungswege, um Unterschiede zwischen der originalen und der potenziell geänderten Liste zu erkennen. Das vorliegende Beispiel soll daher auch für potenzielle "Schwierigkeiten" sensibilisieren, die auch für abweichende Lösungswege relevant sein können.

images/download/attachments/201668199/image-2025-4-9_12-57-28-version-1-modificationdate-1744196248342-api-v2.png