Kaskadierendes Löschen und orphanRemoval
Kaskadierendes Löschen und orphanRemoval
~14 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026
Was passiert, wenn EIN Project mit VORHANDENEN Tasks gelöscht wird? OHNE weitere Konfiguration lehnt die Datenbank das WEGEN der Fremdschlüsselbeziehung AB.
Den Fehler provozieren
curl -k -i -X DELETE https://localhost/api/projects/1HTTP/2 500
{
"hydra:description": "An exception occurred while executing a query: SQLSTATE[23000]: Integrity constraint violation"
}Achtung: Status 500, KEIN sauberer 422 – ein Datenbankfehler ist KEIN Validierungsfehler im Sinne von Kapitel 19, sondern ein UNBEHANDELTER technischer Fehler. Das MUSS behoben werden, ein 500er darf NIE der ERWARTETE Zustand einer API sein.
cascade: ['remove'] auf OneToMany
#[ORM\OneToMany(
targetEntity: Task::class,
mappedBy: 'project',
cascade: ['remove'],
orphanRemoval: true,
)]
#[Groups(['project:read'])]
private Collection $tasks;cascade: ['remove'] löscht AUTOMATISCH ALLE zugehörigen Tasks MIT, sobald das Project gelöscht wird – GENAU dasselbe Konzept wie in der Symfony-Schulung (Kapitel 33).
orphanRemoval erklärt
orphanRemoval: true löst einen ZUSÄTZLICHEN, SUBTILEREN Fall: wird eine Task aus $project->getTasks() ENTFERNT (OHNE sie einem anderen Project zuzuweisen), löscht Doctrine sie AUTOMATISCH, statt sie als "verwaist" (orphan) mit project = NULL in der Datenbank zu belassen – was OHNEHIN unmöglich wäre, da project nullable: false ist (Kapitel 37).
Das neue Verhalten testen
curl -k -i -X DELETE https://localhost/api/projects/1JETZT 204 No Content – das Project UND alle seine Tasks sind weg, OHNE Integritätsfehler.
Achtung: cascade: ['remove'] ist ENDGÜLTIG und UNWIDERRUFLICH – für ein PRODUKTIONSSYSTEM lohnt sich die Abwägung, ob ein "Soft Delete" (deletedAt-Feld statt echtem Löschen) nicht die SICHERERE Wahl ist, besonders bei Daten mit Geschäftswert.
Tipp: Bei der ManyToMany-Beziehung zu Tag (Kapitel 42) ist KEIN cascade: ['remove'] nötig – wird eine Task gelöscht, entfernt Doctrine AUTOMATISCH NUR die Join-Tabellen-Einträge, die eigentlichen Tag-Datensätze bleiben UNBERÜHRT bestehen.