Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1742

Cascade remove doesn't work with inheritance

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Invalid
    • Affects Version/s: 2.2.1
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None
    • Environment:
      Ubuntu 11.10, PHP 5.3.6-13ubuntu3.6 with Suhosin-Patch (cli), MySQL

      Description

      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
      */
      

        Activity

        Hide
        Justin Hendrickson added a comment -

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

        Show
        Justin Hendrickson added a comment - I did some step debugging and it looked like the calculate commit order determined that the person should be removed before the animal.
        Hide
        Benjamin Eberlei added a comment -

        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?

        Show
        Benjamin Eberlei added a comment - 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?
        Hide
        Justin Hendrickson added a comment -

        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.

        Show
        Justin Hendrickson added a comment - 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.
        Hide
        Justin Hendrickson added a comment -

        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 FK_215064B57E3C61F9 FOREIGN KEY (owner_id) 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 AUTO_INCREMENT NOT NULL, owner_id INT DEFAULT NULL, type VARCHAR(255) NOT NULL, INDEX IDX_215064B57E3C61F9 (owner_id), 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.

        Show
        Justin Hendrickson added a comment - 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 FK_215064B57E3C61F9 FOREIGN KEY (owner_id) 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 AUTO_INCREMENT NOT NULL, owner_id INT DEFAULT NULL, type VARCHAR(255) NOT NULL, INDEX IDX_215064B57E3C61F9 (owner_id), 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.
        Hide
        Benjamin Eberlei added a comment -

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

        Show
        Benjamin Eberlei added a comment - Ah yes, i have the same result I ran only against sqlite and they dont have foreign keys. Sorry for that.
        Hide
        Benjamin Eberlei added a comment -

        Its not a bug, your mapping is wrong. The option is cascade=

        {"remove"}

        not cascade=

        {"delete"}
        Show
        Benjamin Eberlei added a comment - Its not a bug, your mapping is wrong. The option is cascade= {"remove"} not cascade= {"delete"}

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Justin Hendrickson
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: