Symfony: A foreign key constraint fails

Symfony bzw. Doctrine verwöhnt. Selbst die komplexesten Datenbank-Strukturen werden von der Kommandozeile generiert und man gewöhnt sich daran, dass man sich um so etwas wie das Löschen von Kind-Elementen nicht mehr kümmern muss. Bis es dann plötzlich mal nicht mehr funktioniert.

In meinem Fall sah das Ganze so aus, dass ich eine Entity Application hatte, welcher beliebig viele Degrees zugeordnet werden konnten, vereinfacht sah der generierte Code wie folgt aus:


class Application
{
    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Degree",
     *   mappedBy="furhterDegreesApplication", 
     *   orphanRemoval=true, cascade={"persist", "remove"})
     */
     private furtherDegrees;
}

und

class Degree
{
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Application",
     * inversedBy="furtherDegrees")
     */
     private $furhterDegreesApplication;
}

Die Relation hat beim Speichern auch funktioniert. Beim Löschen dann aber die Überraschung:

An exception occurred while executing 'DELETE FROM degree WHERE id = ?' with params [1]: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (imb_iss.degree, CONSTRAINT FK_A7A36D631AB0914C FOREIGN KEY (furhter_degrees_application_id) REFERENCES application (id))

Die Lösung fand ich dann in diesem Ticket. Es fehlt ein onDelete=“CASCADE“. Denn das orphanRemoval=true, cascade={„persist“, „remove“} scheint zwar auf ORM Ebene für das Löschen zu sorgen, nicht aber bis runter auf die Datenbank-Ebene, wie hier auf StackOverflow erklärt wird.

Die Entity Degree um @ORM\JoinColumn(onDelete=“CASCADE“) erweitert und es funktionier auch mit dem Löschen:

class Degree
{
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Application",
     * inversedBy="furtherDegrees")
     * @ORM\JoinColumn(onDelete="CASCADE")     
     */
     private $furhterDegreesApplication;
}