DDC-1742: Cascade remove doesn't work with inheritance #2392

Closed
doctrinebot opened this Issue Mar 30, 2012 · 8 comments

2 participants

@doctrinebot

Jira issue originally created by user toxygene:

When removing an entity with a one-to-many relationship with a cascade delete option on it causes a "Integrity constraint violation: 1451 Cannot delete or update a parent row:" error.

<?php
/*** @DiscriminatorColumn(name="type", type="string") @DiscriminatorMap({"cat" = "Cat", "dog" = "Dog"}) @Entity @InheritanceType("SINGLE_TABLE") **/
class Animal
{
    /*** @Column(type="integer") @GeneratedValue @Id **/
    protected $id;

    /*** @ManyToOne(targetEntity="Person",inversedBy="pets") **/
    protected $owner;

    public function setOwner(Person $person) { $this->owner = $person; }
}

/*** @Entity **/
class Cat extends Animal
{
}

/*** @Entity **/
class Dog extends Animal
{
}

/*** @Entity **/
class Person
{
    /*** @Column(type="integer") @GeneratedValue @Id **/
    protected $id;
    /*** @OneToMany(targetEntity="Animal",mappedBy="owner",cascade={"delete"}) **/
    protected $pets;

    public function addPet(Animal $animal) { $animal->setOwner($this); $this->pets[] = $animal; }
}


$person1 = new Person();

$dog1 = new Dog();

$person1->addPet($dog1);

$em->persist($person1);
$em->persist($dog1);

$em->flush();

$em->remove($person1);

$em->flush();

/*
PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`Animal`, CONSTRAINT `FK*6D0726297E3C61F9` FOREIGN KEY (`owner_id`) REFERENCES `Person` (`id`))' in /home/jhendric/public*html/doctrine-test/pear/php/Doctrine/DBAL/Connection.php:754
Stack trace:
#0 /home/jhendric/public_html/doctrine-test/pear/php/Doctrine/DBAL/Connection.php(754): PDOStatement->execute(Array)
#1 /home/jhendric/public_html/doctrine-test/pear/php/Doctrine/DBAL/Connection.php(438): Doctrine\DBAL\Connection->executeUpdate('DELETE FROM Per...', Array)
#2 /home/jhendric/public_html/doctrine-test/pear/php/Doctrine/ORM/Persisters/BasicEntityPersister.php(464): Doctrine\DBAL\Connection->delete('Person', Array)
#3 /home/jhendric/public_html/doctrine-test/pear/php/Doctrine/ORM/UnitOfWork.php(993): Doctrine\ORM\Persisters\BasicEntityPersister->delete(Object(Person))
#4 /home/jhendric/public*html/doctrine-test/pear/php/Doctrine in /home/jhendric/public*html/doctrine-test/pear/php/Doctrine/DBAL/Connection.php on line 754

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`Animal`, CONSTRAINT `FK*6D0726297E3C61F9` FOREIGN KEY (`owner_id`) REFERENCES `Person` (`id`))' in /home/jhendric/public*html/doctrine-test/pear/php/Doctrine/DBAL/Connection.php on line 754

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`Animal`, CONSTRAINT `FK*6D0726297E3C61F9` FOREIGN KEY (`owner_id`) REFERENCES `Person` (`id`)) in /home/jhendric/public*html/doctrine-test/pear/php/Doctrine/DBAL/Connection.php on line 754

Call Stack:
    0.0002     647440   1. {main}() /home/jhendric/public_html/doctrine-test/test.php:0
    0.0513    7989360   2. Doctrine\ORM\EntityManager->flush() /home/jhendric/public_html/doctrine-test/test.php:26
    0.0513    7989440   3. Doctrine\ORM\UnitOfWork->commit() /home/jhendric/public_html/doctrine-test/pear/php/Doctrine/ORM/EntityManager.php:355
*/
@doctrinebot

Comment created by toxygene:

I did some step debugging and it looked like the calculate commit order determined that the person should be removed before the animal.

@doctrinebot

Comment created by @beberlei:

It works for me.

See the testcase attached, you can put it into tests/Doctrine/Tests/ORM/Functional/Ticket, then run "phpunit --group DDC-1742" from the CLI to get the result.

Can you make it fail?

@doctrinebot

Comment created by toxygene:

I ran the provided test and could not reproduce the original error. There were some differences between the original environment and the environment I ran the tests in.

My original environment was a pear install of 2.2.1 and used the MySQL backend. The pear install does not include the unit tests, so I did a github checkout and used that source code for the tests. I initially got an error about not having pdo_sqlite installed, so I'm assuming the unit test used an sqlite(3) database for it's test. I can't imagine how either of these would effect the final result, but I wanted to note them, just in case.

Assuming neither of the previous differences is the source of the problem, I'll try to figure out how to reproduce the problem with a unit test today.

@doctrinebot

Comment created by toxygene:

Using the phpunit.xml file, I setup the unit tests to use MySQL instead of SQLite and I was able to reproduce the error:

jhendric@jhendric-Ubuntu:~/public_html/doctrine2-test/doctrine2-orm$ phpunit --group DDC-1742
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /home/jhendric/public_html/doctrine2-test/doctrine2-orm/phpunit.xml

E

Time: 1 second, Memory: 72.50Mb

There was 1 error:

1) Doctrine\Tests\ORM\Functional\Ticket\DDC1742Test::testIssue
Exception: [PDOException] SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (doctrine*tests.DDC1742Animal, CONSTRAINT FK_215064B57E3C61F9 FOREIGN KEY (owner*id) REFERENCES DDC1742Person (id))

With queries:
6. SQL: 'INSERT INTO DDC1742Animal (owner_id, type) VALUES (?, ?)' Params: '1', 'dog'
5. SQL: 'INSERT INTO DDC1742Person (id) VALUES (null)' Params:
4. SQL: 'ALTER TABLE DDC1742Animal ADD CONSTRAINT FK215064B57E3C61F9 FOREIGN KEY (ownerid) REFERENCES DDC1742Person (id)' Params:
3. SQL: 'CREATE TABLE DDC1742Person (id INT AUTO_INCREMENT NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB' Params:
2. SQL: 'CREATE TABLE DDC1742Animal (id INT AUTOINCREMENT NOT NULL, owner_id INT DEFAULT NULL, type VARCHAR(255) NOT NULL, INDEX IDX_215064B57E3C61F9 (ownerid), PRIMARY KEY(id)) ENGINE = InnoDB' Params:

Trace:
/home/jhendric/public_html/doctrine2-test/doctrine2-orm/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Connection.php:754
/home/jhendric/public_html/doctrine2-test/doctrine2-orm/lib/vendor/doctrine-dbal/lib/Doctrine/DBAL/Connection.php:438
/home/jhendric/public_html/doctrine2-test/doctrine2-orm/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php:464
/home/jhendric/public_html/doctrine2-test/doctrine2-orm/lib/Doctrine/ORM/UnitOfWork.php:993
/home/jhendric/public_html/doctrine2-test/doctrine2-orm/lib/Doctrine/ORM/UnitOfWork.php:331
/home/jhendric/public_html/doctrine2-test/doctrine2-orm/lib/Doctrine/ORM/EntityManager.php:355
/home/jhendric/public_html/doctrine2-test/doctrine2-orm/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1742Test.php:38

/home/jhendric/public_html/doctrine2-test/doctrine2-orm/tests/Doctrine/Tests/OrmFunctionalTestCase.php:401

FAILURES!
Tests: 1, Assertions: 0, Errors: 1.

@doctrinebot

Comment created by @beberlei:

Ah yes, i have the same result I ran only against sqlite and they dont have foreign keys. Sorry for that.

@doctrinebot

Comment created by @beberlei:

Its not a bug, your mapping is wrong. The option is cascade={"remove"} not cascade={"delete"}

@doctrinebot

Issue was closed with resolution "Invalid"

@beberlei beberlei was assigned by doctrinebot Dec 6, 2015
@doctrinebot doctrinebot closed this Dec 6, 2015
@doctrinebot doctrinebot added the Bug label Dec 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment