DDC-2424: Removing an inherited entity via a delete cascade constraint does not remove the parent row #3040

Open
opened 2026-01-22 14:10:36 +01:00 by admin · 10 comments
Owner

Originally created by @doctrinebot on GitHub (May 2, 2013).

Originally assigned to: @beberlei on GitHub.

Jira issue originally created by user xaapyks:

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)

Originally created by @doctrinebot on GitHub (May 2, 2013). Originally assigned to: @beberlei on GitHub. Jira issue originally created by user xaapyks: For a parent class: ```php /** * @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: ```php 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)
admin added the Bug label 2026-01-22 14:10:36 +01:00
Author
Owner

@doctrinebot commented on GitHub (May 4, 2013):

Comment created by @beberlei:

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?

@doctrinebot commented on GitHub (May 4, 2013): Comment created by @beberlei: 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?
Author
Owner

@doctrinebot commented on GitHub (May 6, 2013):

Comment created by xaapyks:

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;
@doctrinebot commented on GitHub (May 6, 2013): Comment created by xaapyks: ```sql 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; ```
Author
Owner

@doctrinebot commented on GitHub (May 6, 2013):

Comment created by xaapyks:

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.

@doctrinebot commented on GitHub (May 6, 2013): Comment created by xaapyks: 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.
Author
Owner

@doctrinebot commented on GitHub (May 6, 2013):

Comment created by xaapyks:

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.

@doctrinebot commented on GitHub (May 6, 2013): Comment created by xaapyks: 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.
Author
Owner

@doctrinebot commented on GitHub (Apr 25, 2014):

Comment created by L:

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

@doctrinebot commented on GitHub (Apr 25, 2014): Comment created by L: I've got a similar problem but I have InheritanceType("SINGLE_TABLE") instead of JOINED. Any updates on when this is getting fixed?
Author
Owner

@vyshkant commented on GitHub (Dec 12, 2017):

@beberlei Hi! Any progress on this issue?

@vyshkant commented on GitHub (Dec 12, 2017): @beberlei Hi! Any progress on this issue?
Author
Owner

@Ocramius commented on GitHub (Jul 23, 2018):

@R1Daneel send a test case and start proposing a patch 👍

@Ocramius commented on GitHub (Jul 23, 2018): @R1Daneel send a test case and start proposing a patch :+1:
Author
Owner

@meiyasan commented on GitHub (Sep 10, 2021):

Hello @beberlei @Ocramius, is this issue fixed ?
I am facing a similar issue when deleting from my phpMyAdmin page. I get then an orphan parent class entry when deleting the child class

@meiyasan commented on GitHub (Sep 10, 2021): Hello @beberlei @Ocramius, is this issue fixed ? I am facing a similar issue when deleting from my phpMyAdmin page. I get then an orphan parent class entry when deleting the child class
Author
Owner

@Hortich commented on GitHub (Apr 7, 2022):

Same problem for me...

@Hortich commented on GitHub (Apr 7, 2022): Same problem for me...
Author
Owner

@7system7 commented on GitHub (Apr 12, 2023):

Same here. I created a workaround for that. 😢

@7system7 commented on GitHub (Apr 12, 2023): Same here. I created a workaround for that. :cry:
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#3040