CodamAIDocs
Themafertig

Abhängige Objekte (Kaskaden)

Wann Kinder mitgelöscht und wann nur abgekoppelt werden, dass jedes Kind seine eigene Löschrolle braucht und dass eine fehlende Rolle alles zurückrollt.

Ausprägungen
mit DELETE-Flag → mitgelöschtohne DELETE-Flag → abgekoppeltje Beziehungstyp: 1:1, 1:n, n:1, n:m, Verbindungsmodellüber mehrere StufenRolle fehlt irgendwo → alles zurückFeldrolle statt Klassenrolle

Worum es geht

Ein Objekt steht selten allein. Eine Firma hat Mitarbeiter, eine Rechnung hat Positionen, ein Mitarbeiter gehört zu einer Abteilung. Löschst du ein Objekt, geht CDMS jede seiner Beziehungen durch und entscheidet für jedes verbundene Objekt:

  • mitlöschen, wenn die Beziehung das Flag DELETE hat. Das verbundene Objekt ist dann ein abhängiges Kind: Es lebt nur mit seinem Elternobjekt.
  • abkoppeln, wenn die Beziehung kein DELETE hat. Das verbundene Objekt bleibt bestehen, nur der Verweis auf das gelöschte Objekt verschwindet.

Ein mitgelöschtes Kind wird genauso behandelt wie das Objekt selbst: Auch seine Beziehungen werden durchgegangen. So kann eine Löschung über viele Stufen reichen. Diese Kettenreaktion heißt Kaskade.

Ein Beispiel als Baum

Eine Firma mit dieser Modellierung:

FeldTypFlag DELETE
Company.employees1:n auf Mitarbeiterja
Employee.phones1:n auf Telefonnummerja
Company.logo1:1 auf ein Datei-Modellja
Company.mainAddress1:1 auf Adressenein
Employee.departmentn:1 auf Abteilungnein

DELETE /company/delete/c4… wirkt so:

flowchart TB
    C["Firma CodamIC"]:::weg --> E1["Mitarbeiter Anna"]:::weg
    C --> E2["Mitarbeiter Ben"]:::weg
    C --> L["Logo (Datei)"]:::weg
    C -.-> A["Adresse Wiesbaden"]:::bleibt
    E1 --> P1["Telefon 0611-1"]:::weg
    E2 --> P2["Telefon 0611-2"]:::weg
    E2 --> P3["Telefon 0170-3"]:::weg
    E1 -.-> D["Abteilung IT"]:::bleibt
    E2 -.-> D
    classDef weg fill:#fdecea,stroke:#c62828,color:#8e0000
    classDef bleibt fill:#e8f5e9,stroke:#2e7d32,color:#1b5e20

Rot wird gelöscht, grün bleibt. Durchgezogene Linien sind Beziehungen mit DELETE-Flag, gestrichelte ohne.

  • Anna, Ben und ihre Telefonnummern werden gelöscht, über zwei Stufen.
  • Das Logo wird gelöscht, samt Dateiinhalt im Speicher. Siehe Datei-Modelle löschen.
  • Die Adresse bleibt. Sie verliert nur ihren Verweis auf die Firma.
  • Die Abteilung IT bleibt. Anna und Ben verschwinden aus ihrer Liste employees.

Abkoppeln oder mitlöschen, je Beziehungstyp

Was mit dem verbundenen Objekt passiert, wenn X gelöscht wird
Beziehung an XFlag DELETEErgebnis
1:1jadas Kind wird gelöscht
1:1neindas Kind bleibt, sein Verweis auf X wird geleert
1:n (Liste)jaalle Kinder in der Liste werden gelöscht
1:n (Liste)neinalle Kinder bleiben, ihr Verweis auf X wird geleert
n:1 (X zeigt auf ein Elternobjekt)neindas Elternobjekt bleibt, X verschwindet aus seiner Liste
n:1 (X zeigt auf ein Elternobjekt)jadas Elternobjekt wird gelöscht
n:mneindie Verbindungen verschwinden, die Partner bleiben
n:mjawie ohne Flag: die Verbindungen verschwinden, die Partner bleiben

Bei einem Verbindungsmodell (n:m mit eigenen Feldern, etwa Group2User) sind es zwei 1:n-Beziehungen. Hat User.groups das DELETE-Flag, löscht CDMS mit dem Benutzer seine Verbindungszeilen. Die Gruppen bleiben, weil Group2User.group kein DELETE-Flag hat. Siehe Many-to-Many über eine Verbindungstabelle.

Abkoppeln im Einzelnen

Abkoppeln heißt: CDMS leert beim verbundenen Objekt den Verweis zurück auf das gelöschte Objekt und speichert es. Das verbundene Objekt selbst bleibt, mit allen anderen Feldern.

Die beiden Wege
Mitlöschen
Beziehung mit DELETE
  • das Kind verschwindet mit seinen eigenen abhängigen Kindern
  • braucht die Löschrolle des Kindmodells
  • DELETE-Hooks des Kindes laufen
  • Dateiinhalt des Kindes wird entfernt
Abkoppeln
Beziehung ohne DELETE
  • das Objekt bleibt, nur der Verweis wird leer
  • keine Rolle des verbundenen Modells nötig
  • keine DELETE-Hooks
  • Dateien bleiben unberührt

Weil Abkoppeln kein Löschen ist, brauchst du dafür keine Rolle am verbundenen Modell. Einen Mitarbeiter darfst du mit employee-delete löschen, auch ohne jede Rolle an der Abteilung. Die Abteilung bleibt und hat ihn danach nicht mehr in employees.

Rollen in der Kaskade

CDMS prüft die Löschrolle für jede Zeile, die verschwindet, und zwar gegen das Modell dieser Zeile. Wer eine Firma samt Mitarbeitern löschen will, braucht company-delete und employee-delete.

Die Rollenprüfung in einer Kaskade

Wann: company-delete und employee-delete

  1. 1
    CDMS
    Firma: company-delete vorhanden
  2. 2
    CDMS
    jeder Mitarbeiter: employee-delete vorhanden
  3. 3
    CDMS→Database
    löscht Firma und Mitarbeiter

Ergebnis: 200

Wann: nur company-delete, die Firma hat einen Mitarbeiter

  1. 1
    CDMS
    Firma: company-delete vorhanden
  2. 2
    CDMS
    Mitarbeiter: employee-delete fehlt
  3. 3
    CDMS→Client
    403 missing-permission|employee-delete, die Transaktion wird zurückgerollt

Ergebnis: Firma und Mitarbeiter sind danach unverändert da. Es gibt kein „halb gelöscht“.

Wann: Die Beziehung Vault.notes hat eine eigene Löschrolle vault-notes-delete

  1. 1
    CDMS
    Tresor: vault-delete vorhanden
  2. 2
    CDMS
    jede Notiz: vault-notes-delete oder note-delete vorhanden?
  3. 3
    CDMS→Database
    löscht Tresor und Notizen

Ergebnis: Die Feldrolle erlaubt das Löschen der Notizen nur über diesen Weg. Eine Notiz direkt über /note/delete/{id} zu löschen, verlangt weiter note-delete. Fehlt beides, nennt der Fehler die Feldrolle: 403 missing-permission|vault-notes-delete.

Eine Feldrolle gilt nur für eine Stufe. Hat eine Notiz selbst abhängige Kinder, braucht jedes davon wieder die Rolle seines Modells oder eine Feldrolle an der Beziehung der Notiz. Siehe Rechte auf Beziehungen (Feldrollen).

Fallen

Wie es weitergeht

Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-system-layer – AbstractLayer.recursiveDelete, removeBackReference, enterField, grantedByField
  • CDMS/cdms-authorization – AbstractAuthorizationLayer.deleteAccessAllowedByClass, accessGrantedByField
  • CDMS/cdms-integrationtest – AbstractRecursiveTest, AbstractRecursiveDelete, AbstractRoleDenialTest (cascadedDeleteNeedsTheDeleteRoleOfTheChild, Mitarbeiter löschen ohne Abteilungsrolle), AbstractFieldRoleTest (cascadedDeleteThroughTheFieldRole, cascadedDeleteWithoutTheFieldRoleIsRefused), AbstractRecursiveFileDeleteTest
  • documentation/20-api/04-schreibsemantik.md, 30-daten-und-persistenz/03-beziehungen.md
Suchen