CodamAIDocs
Themafertig

Hooks bei verschachtelten Objekten und Kaskaden

Hooks feuern auch für Kinder und kaskadiert gelöschte Objekte. Wie sie gesammelt und in welcher Reihenfolge ausgeführt werden, und wann keine Hooks feuern.

Ausprägungen
Kind angelegtKind geändertKind kaskadiert gelöschtKind nur entkoppelt (kein Hook)Kind nur verknüpft (kein Hook)Reihenfolge: Operationen, Eltern und KinderREAD-Hooks für ausgebaute Referenzen

Worum es geht

Eine Anfrage schreibt oft mehr als ein Objekt: eine Firma mit neuen Mitarbeitern, eine Rechnung mit ihren Positionen, ein Löschen, das abhängige Kinder mitnimmt. Jedes dieser Objekte bekommt seine eigenen Hooks, also die Hooks seines Modells, mit seiner Operation.

CDMS führt diese Hooks nicht sofort aus. Während der Rekursion trägt es jedes Objekt in zwei Warteschlangen ein, eine für die Before-Hooks und eine für die After-Hooks. Eine Warteschlange ist eine Liste, die in der Reihenfolge des Eintragens abgearbeitet wird. Erst wenn der ganze Baum durchlaufen ist, arbeitet CDMS sie ab.

Welches Kind welche Hooks bekommt

Ein Kind in einem verschachtelten Schreibvorgang

Wann: Kind ohne id, die Beziehung hat CREATE

  1. 1
    CDMS
    legt das Kind über den System-Layer seines Modells an
  2. 2
    Hook
    Before- und After-Hooks des Kindmodells mit CREATE

Ergebnis: Das gilt bei Create, PUT und PATCH des Elternobjekts gleich: Das neue Kind bekommt immer CREATE.

Wann: Kind mit id, die Beziehung hat UPDATE; bei PATCH auch jeder Listeneintrag mit id

  1. 1
    CDMS
    überträgt die gesendeten Werte auf das Kind
  2. 2
    Hook
    Before- und After-Hooks des Kindmodells mit UPDATE (bei Create und PUT) oder PATCH (bei PATCH)

Ergebnis: Welche Kinder mitgeändert werden, steht unter Die vier Fälle beim verschachtelten Schreiben.

Wann: abhängiges Kind (Beziehung mit DELETE), beim Löschen des Elternobjekts oder weil es bei PUT oder PATCH aus der Beziehung fällt

  1. 1
    CDMS
    prüft die Löschrolle des Kindes und nimmt es zum Entfernen vor
  2. 2
    Hook
    Before- und After-Hooks des Kindmodells mit DELETE
  3. 3
    CDMS
    geht die Beziehungen des Kindes genauso durch, über beliebig viele Stufen

Ergebnis: Siehe Abhängige Objekte (Kaskaden) und Löschen durch Ändern.

Wann: Beziehung ohne DELETE: das Kind fällt aus der Beziehung oder das Elternobjekt wird gelöscht

  1. 1
    CDMS→Database
    leert nur den Verweis zwischen den beiden Objekten
  2. 2
    Hook
    keine Hooks für das Kind

Ergebnis: Das Kind bleibt bestehen. Für CDMS ist das keine Operation auf dem Kind.

Wann: Kind mit id, die Beziehung hat kein UPDATE (bei Create, PUT und PATCH-Einzelreferenzen)

  1. 1
    CDMS
    setzt nur den Verweis auf das bestehende Kind
  2. 2
    Hook
    keine Hooks für das Kind

Ergebnis: Das Kind selbst wird nicht geändert.

Die Warteschlange an einem Beispiel

Eine Abteilung hat eine Liste employees. Die Beziehung hat die Flags CREATE, UPDATE und DELETE. Vor der Anfrage gehören Anna und Ben zur Abteilung. Der Client schickt ein PUT:

PUT mit einem geänderten, einem neuen und einem weggelassenen Mitarbeiter
Anfrage
PUT /api/rest/org/department/update/d-1
{
  "data": {
    "id": "d-1",
    "name": "Vertrieb Nord",
    "employees": [
      { "id": "e-anna", "name": "Anna Berg" },
      { "name": "Cem" }
    ]
  },
  "response": ["id"]
}
Antwort
200, { "data": { "id": "d-1" }, … }
flowchart TB
    D["Abteilung d-1<br/>UPDATE"] --> A["Anna<br/>UPDATE"]
    D --> C["Cem, neu<br/>CREATE"]
    D -.-> B["Ben, weggelassen<br/>DELETE"]

CDMS geht die Abteilung durch und trägt dabei in die Warteschlangen ein:

Rekursion: Einträge in die Warteschlangen
  1. 1
    CDMS
    Abteilung: Before-Eintrag UPDATE
  2. 2
    CDMS
    Ben fehlt in der Liste und ist abhängig: Before- und After-Eintrag DELETE, Ben wird zum Entfernen vorgemerkt
  3. 3
    CDMS
    Anna: Before-Eintrag UPDATE, Werte übertragen, After-Eintrag UPDATE
  4. 4
    CDMS
    Cem: Before-Eintrag CREATE, Werte übertragen, After-Eintrag CREATE
  5. 5
    CDMS
    Abteilung fertig: After-Eintrag UPDATE

Dann arbeitet CDMS die Warteschlangen ab, je Operation in der festen Reihenfolge CREATE, UPDATE, PATCH, DELETE:

SchrittBefore-HooksAfter-Hooks
1 · CREATECemCem
2 · UPDATEAbteilung, dann AnnaAnna, dann Abteilung
3 · DELETEBenBen

Zwischen den beiden Spalten liegen Validierung und Speichern, siehe Die Reihenfolge in einem Schreibvorgang. Innerhalb einer Operation laufen die Before-Hooks in der Reihenfolge des Eintragens, also das Elternobjekt vor seinen Kindern. Die After-Hooks trägt CDMS erst ein, wenn ein Objekt samt Kindern fertig ist. Deshalb laufen dort die Kinder vor dem Elternobjekt.

Die Reihenfolge der Operationen geht vor die Baumstruktur. Im Beispiel läuft der Before-Hook des neuen Kindes Cem vor dem Before-Hook der Abteilung, weil CREATE vor UPDATE drankommt.

Kaskade beim Löschen

Beim DELETE gibt es nur eine Operation. Hier bestimmt der Baum allein die Reihenfolge:

flowchart TB
    F["Firma<br/>before 1 · after 5"] --> A1["Abteilung Nord<br/>before 2 · after 3"]
    A1 --> P1["Team N-1<br/>before 3 · after 1"]
    A1 --> P2["Team N-2<br/>before 4 · after 2"]
    F --> A2["Abteilung Süd<br/>before 5 · after 4"]
    F -.-> K["Kunde, nur abgekoppelt<br/>kein Hook"]

Die Before-Hooks laufen von oben nach unten, die After-Hooks von unten nach oben. Das Elternobjekt sieht in seinem After-Hook also, dass alle Kinder schon behandelt sind.

Wenn die Before-Hooks laufen, hat CDMS die Rekursion schon hinter sich:

  • Jedes abhängige Kind ist aus den Beziehungsfeldern seines Elternobjekts genommen und zum Entfernen vorgemerkt. Der Before-Hook der Firma findet ihre Abteilungen nicht mehr in ihrer Liste. Jede Abteilung bekommt dafür ihren eigenen Hook, mit allen ihren Feldern.
  • Die Rollen aller Objekte sind geprüft. Fehlt bei einem Kind die Löschrolle, läuft kein einziger Hook.
  • Ein Before-Hook, der eine Exception wirft, verhindert das Löschen des ganzen Baums, egal auf welcher Stufe er sitzt.

Entscheidungstabelle

Bekommt ein verbundenes Objekt Hooks?
Was mit dem Objekt passiertFlag an der BeziehungHooks des Objekts
neu, ohne idCREATECREATE
mit id, Werte gesendetUPDATEUPDATE bei Create und PUT, PATCH bei PATCH
mit id, nur verknüpftkein UPDATEkeine
fällt aus der Beziehung oder Elternobjekt wird gelöschtDELETEDELETE, auch für seine eigenen abhängigen Kinder
fällt aus der Beziehung oder Elternobjekt wird gelöschtkein DELETEkeine, nur der Verweis wird geleert

Beim Zurücklesen: READ-Hooks

Nach einem Create, PUT oder PATCH liest CDMS das Objekt mit der response der Anfrage zurück. Jede ausgebaute Referenz und jeder Eintrag einer ausgebauten Liste ist dabei ein eigenes Lesen über das eigene Modell, mit eigenem READ-Hook. Fordert die Antwort im Beispiel employees mit an, laufen die READ-Hooks der Abteilung und jedes Mitarbeiters. Siehe Referenzen und Listen ausbauen.

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-system-layer – AbstractLayer (recursiveCreate, setModel, recursiveUpdate, recursivePatch, recursivePrepare (_reference), reduceToTargetState, detachOrDeleteModel, detachOrDeleteMember, recursiveDelete, fetchAndSetModel, fetchAndSetList)
  • CDMS/cdms-system-layer – session/HookRequestContext (addHookBefore, addHookAfter, take, runAllBefore, runAllAfter: CREATE, UPDATE, PATCH, DELETE, ROLLBACK)
  • CDMS/cdms-system-layer – HookManagementSystem (Hooks je konkreter Entity-Klasse)
  • CDMS/cdms-integrationtest – TestHookManagement, AbstractRecursiveDelete, AbstractRecursivePatch
  • documentation/60-erweiterung/01-hooks.md
Suchen