Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1414

UnitOfWork#getCommitOrder() does not add dependencies for all related classes

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.1.2, Git Master
    • Fix Version/s: 2.1.3
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None
    • Environment:
      All

      Description

      getCommitOrder() does not add dependencies for all related classes. This causes database-level exceptions in certain cases, as insertion order can be calculated incorrectly, and foreign key constraints fail.

      An example case in pseudocode:

      A: ManyToOne to B, nullable=true
      B: ManyToOne to C, nullable=false
      C: no owning relations
      
      a = new A()
      em->persist(a)
      em->flush()     // does CommitOrderCalculator->addClass(B), but does not add B's dependency to C
      
      c = new C()
      b = new B(c)
      
      em->persist(c)
      em->persist(b)
      em->flush()     // CommitOrderCalculator->hasClass(B) == true, dependencies not added, foreign key constraint fails
      

      Suggested fix against master:

      diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php
      index ea516f3..991acac 100644
      --- a/lib/Doctrine/ORM/UnitOfWork.php
      +++ b/lib/Doctrine/ORM/UnitOfWork.php
      @@ -853,6 +853,7 @@ class UnitOfWork implements PropertyChangedListener
                           $targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
                           if ( ! $calc->hasClass($targetClass->name)) {
                               $calc->addClass($targetClass);
      +                        $newNodes[] = $targetClass;
                           }
                           $calc->addDependency($targetClass, $class);
                           // If the target class has mapped subclasses,
      

      This $newNodes[] push is done for all new classes in $entityChangeSet (above) and $targetClass->subClasses (below), but not for $targetClass itself. I'm assuming this is a bug, not by design.

        Activity

        Hide
        Benjamin Eberlei added a comment -

        Fixed.

        Show
        Benjamin Eberlei added a comment - Fixed.

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Petri Mahanen
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: