Neue Instanz oder nur eine Referenz? Wann liefert ein Retrieve was?

Mai 7, 2021 0 Von Andreas

Ich bin auf dieses Thema gestoßen weil es in einem echten Projekt zu einem echten Problem geführt hat. Innerhalb eines recht langen Prozesses hat sich durch eine Änderung im Code der Status eines Objektes von autocommitted zu normal verändert. Dies hatte dann an einer völlig anderen Stelle zur Folge, dass unser Programm nicht mehr reagiert hat wie vorher. Änderungen an einem Objekt fanden sich plötzlich nicht mehr in der Datenbank wieder.

Was war passiert?

Betrachten wir zunächst folgendes Datenmodel.

Die Attribute der beiden Entitäten sind hierbei egal. Es könnten auch beliebige andere Attribute und Typen sein.

Die zu committenden Objekte B befanden sich in einer Liste. Am Ende des Prozesses wurde eben diese Liste committed. Davor allerdings, wurde über eine Liste A iteriert. Innerhalb dieser Iteration wurden über einen Retrieve by association die Objekte des Typ B einzeln retrieved und es wurden in einer Change Action Werte darin verändert. In einer vorherigen Version spiegelten sich diese Änderungen auch in der Liste wieder. Das Retrieve by association hat also eine weitere Referenz auf die gleiche Instanz des Objektes erstellt welche sich bereits in der Liste befindet. Beim Committen der Liste wurden die Änderungen mit committet und fanden sich in der Datenbank wieder.

Nach einer Code Änderung an anderer Stelle verhielt es sich allerdings völlig anders. Das Retrieve by association hat nun eine neue Instanz des gleichen Objektes erstellt. Die Änderungen welche in der Iteration getätigt wurden fanden sich somit nicht mehr in der Liste wieder und wurden auch nicht in die Datenbank geschrieben.

Aber warum?

Was hatte sich also verändert? Nach Wiederherstellen der Vorgängerversion und einem direkten Vergleich kam heraus, dass die Objekte von B zum Zeitpunkt der Iteration den Status ‚autocommitted‘ hatten. In der neuen Version hatten sie allerdings den Status ’normal‘.

Die Vermuting lag nahe, dass der Status darüber entscheidet ob eine gegachte Version eines Objektes neu referenziert oder ob eine neue Instanz des Objektes erstellt wird.

Wie verhält sich welcher Status?

Um das herauszufinden habe ich eine einfache Demo Anwendung kreiert die das Szenario mit allen Möglichen Varianten durchspielt. Herausgekommen ist, dass Retrieves by Association auf Objekte im Status ‚Instantiated‘ oder ‚Autocommitted‘ eine neue Referenz auf das im Cache vorhandene Objekt erzeugen während das gleiche Retrieve auf ein Objekt im Status ‚Normal‘ eine neue Instanz erstellt, auch wenn sich das Objekt noch im Cache befindet.

Fazit

Wenn man es sich beim Entwickeln eines Microflows zu Nutze macht, dass man bei einem Retrieve by association wahlweise eine neue Instanz oder lediglich eine Referenz erstellt, so muss man unbedingt im Auge behalten welche Zustände die Objekte zum Zeitpunkt der Ausführung haben können und ob diese unter Umständen durch Code Updates verändert werden können. Ändern sie sich nämlich, so kann das unerwartete Konsequenzen haben. Gerade in komplexen Prozessen sind diese Fehler nicht leicht zu finden, da Ursache und Wirkung an komplett unterschiedlichen Stellen im Code liegen können.

Viel Spaß beim Ausprobieren. Ich freue mich wie immer über euer Feedback.