Search code examples
symfonyormdoctrine-ormmodelsymfony4

Cannot delete or update a parent row constraint violation with cascade remove


I have 2 entites : Information and PossibleAnswer Information can be seen as a question, depending on its type, it can have PossibleAnswers. It can also have a child Information, if the parent Information has PossibleAnswers, one of them will trigger the child dipslay.

Information class :

/**
 * @ORM\Entity(repositoryClass="App\Repository\InformationRepository")
 */
class Information
{

    use DateTrait;

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string")
     * @Assert\NotBlank()
     */
    private $name;

    /**
     * @var string
     *
     * @ORM\Column(type="string")
     * @Assert\NotBlank()
     */
    private $type;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\PossibleAnswer", mappedBy="information", cascade={"persist", "remove"}, orphanRemoval=true)
     */
    private $possibleanswers;

    /**
     * One Information has Many Informations.
     * @ORM\OneToMany(targetEntity="Information", mappedBy="parent", cascade={"remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"rank" = "ASC"})
     */
    private $children;

    /**
     * Many Informations have One Information.
     * @ORM\ManyToOne(targetEntity="Information", inversedBy="children")
     */
    private $parent;

    /**
     * réponse qui déclenche une sous question
     * @ORM\ManyToOne(targetEntity="PossibleAnswer")
     */
    private $trigger;

PossibleAnswer class :

/**
 * @ORM\Entity(repositoryClass="App\Repository\PossibleAnswerRepository")
 */
class PossibleAnswer
{

    use DateTrait;

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Information", inversedBy="possibleanswers")
     */
    private $information;

    /**
     * @var string
     *
     * @ORM\Column(type="string")
     * @Assert\NotBlank()
     */
    private $value;

Now I want to delete a specific Information and delete every PossibleAnswer or child Information. But some delete cases are not working :

  1. Single Information : OK
  2. Information with child Information : OK
  3. Information with PossibleAnswers : OK
  4. Information with PossibleAnswers triggering a child Information : KO
  5. Information with child Information whit PossibleAnswers : KO

In case 4 :

An exception occurred while executing 'DELETE FROM possible_answer WHERE id = ?' with params [28]:

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (evisa.information, CONSTRAINT FK_297918835FDDDCD6 FOREIGN KEY (trigger_id) REFERENCES possible_answer (id))

In case 5 :

An exception occurred while executing 'DELETE FROM information WHERE id = ?' with params [56]:

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (db.possible_answer, CONSTRAINT FK_3D79739D2EF03101 FOREIGN KEY (information_id) REFERENCES information (id))

I'm missing something in my cascading to delete everything correctly, but I can't find what it is.


Solution

  • You are using ORM level cascades, what you are trying to achieve is Database Level cascade http://www.inanzzz.com/index.php/post/6s4g/one-to-many-association-cascade-example-with-doctrine-annotations What you need is onDelete="CASCADE" For example: /** * @ORM\ManyToOne(targetEntity="App\Entity\Information", inversedBy="possibleanswers") * @JoinColumn(onDelete="CASCADE") */ private $information; Always use JoinColumn you will have more control over your code and manually name columns, otherwise you will end up with a mess in your database, some names will be CamelCase some snake_case.