Skip to content

Loading…

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

Closed
doctrinebot opened this Issue · 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
@doctrinebot doctrinebot closed this
@doctrinebot doctrinebot added the Bug label
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.