Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-2424

Removing an inherited entity via a delete cascade constraint does not remove the parent row

    Details

    • Type: Bug Bug
    • Status: Awaiting Feedback
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.3.3, 2.4.6
    • Fix Version/s: None
    • Component/s: None
    • Environment:
      Mysql 5.1.66 / Symfony 2.2.1

      Description

      For a parent class:

      /**
       * @ORM\Entity
       * @ORM\Table(name="Base")
       * @ORM\InheritanceType("JOINED")
       * @ORM\DiscriminatorColumn(name="discr", type="string")
       * @ORM\DiscriminatorMap({"child1" = "Child1", "child2" = "Child2"})
       */
      

      and simple Child1 & Child2 entities.

      With another entity (let's call it ExternalEntity) having a bidirectional OneToOne relation owned by Child1:

      class Child1 extends Base
      {
        /**
         * @ORM\OneToOne(targetEntity="ExternalEntity", inversedBy="xxx")
         * @ORM\JoinColumn(onDelete="CASCADE", nullable=false)
         */
         private theForeignKey;
      }
      

      Enough for the context.
      The symptoms:

      $em->remove(instanceOfExternalEntity);

      removes the ExternalEntity row and the Child1 row. But a dangling row in the Base table is still there for the now inexistent Child1 instance.

      Though, a manual delete of either the associated Child1 OR Base row and then the ExternalEntity works.

      The problem with the cascading deletion of the parent seems to be only present when deleting through a MYSQL cascading delete from another row which has a foreign key on a child. (Not tested with a foreign key on the parent though)

        Activity

        Hide
        J added a comment -

        I've got a similar problem but I have InheritanceType("SINGLE_TABLE") instead of JOINED.
        Any updates on when this is getting fixed?

        Show
        J added a comment - I've got a similar problem but I have InheritanceType("SINGLE_TABLE") instead of JOINED. Any updates on when this is getting fixed?
        Hide
        Bruno Jacquet added a comment -

        Maybe using

        cascade={"remove"}

        , instead of

        onDelete="CASCADE"

        to force the cascading process to be handled by doctrine would workaround the bug... But I prefer to have my DB do the logic work as much as possible.

        Show
        Bruno Jacquet added a comment - Maybe using cascade={ "remove" } , instead of onDelete= "CASCADE" to force the cascading process to be handled by doctrine would workaround the bug... But I prefer to have my DB do the logic work as much as possible.
        Hide
        Bruno Jacquet added a comment - - edited

        The problem is that, the SQL model never explicitely tells the DB to delete the corresponding Base when Child1 gets removed. It looks like it is handled by the doctrine entity manager layer and not the actual DB engine (Base has no on delete cascade nor foreign key to its children).
        So only doctrine can add the logic here because it knows the entity schema. But in this case, when it is deleted from another table, it looks like the special treatment is not triggered.

        Show
        Bruno Jacquet added a comment - - edited The problem is that, the SQL model never explicitely tells the DB to delete the corresponding Base when Child1 gets removed. It looks like it is handled by the doctrine entity manager layer and not the actual DB engine (Base has no on delete cascade nor foreign key to its children). So only doctrine can add the logic here because it knows the entity schema. But in this case, when it is deleted from another table, it looks like the special treatment is not triggered.
        Hide
        Bruno Jacquet added a comment -

        CREATE TABLE Base (id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
        CREATE TABLE Child1 (id INT NOT NULL, foreignKey INT NOT NULL, UNIQUE INDEX UNIQ_179B6E88E992F5A (foreignKey), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;

        ALTER TABLE Child1 ADD CONSTRAINT FK_179B6E88E992F5A FOREIGN KEY (foreignKey) REFERENCES ExternalEntity (id) ON DELETE CASCADE;
        ALTER TABLE Child1 ADD CONSTRAINT FK_179B6E8BF396750 FOREIGN KEY (id) REFERENCES Base (id) ON DELETE CASCADE;

        Show
        Bruno Jacquet added a comment - CREATE TABLE Base (id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB; CREATE TABLE Child1 (id INT NOT NULL, foreignKey INT NOT NULL, UNIQUE INDEX UNIQ_179B6E88E992F5A (foreignKey), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB; ALTER TABLE Child1 ADD CONSTRAINT FK_179B6E88E992F5A FOREIGN KEY (foreignKey) REFERENCES ExternalEntity (id) ON DELETE CASCADE; ALTER TABLE Child1 ADD CONSTRAINT FK_179B6E8BF396750 FOREIGN KEY (id) REFERENCES Base (id) ON DELETE CASCADE;
        Hide
        Benjamin Eberlei added a comment -

        Can you show the CREATE TABLE and FOREIGN KEY statements of all the tables involved? It seems the cascade of the foreign keys is not propagated between multiple tables?

        Show
        Benjamin Eberlei added a comment - Can you show the CREATE TABLE and FOREIGN KEY statements of all the tables involved? It seems the cascade of the foreign keys is not propagated between multiple tables?

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Bruno Jacquet
          • Votes:
            3 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated: