Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1968

CommitOrderCalculator fails to calculate right order for mixing one-to-many and one-to-one relations

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Invalid
    • Affects Version/s: 2.0.7
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All
    • Labels:

      Description

      I have 2 classes. Zone and Rotator.
      Zone relates to Rotator as One-to-Many. And Zone COULD realte to Rotator as One-to-One. Here is code snippet:

       
      class Zone
      {
          /**
           * @var integer $id
           *
           * @ORM\Column(name="id", type="integer")
           * @ORM\Id
           * @ORM\GeneratedValue(strategy="AUTO")
           */
          private $id;
      
          /**
           * @ORM\OneToMany(targetEntity="Rotator", mappedBy="zone", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
           * @ORM\OrderBy({"id" = "ASC"})
           */
          private $rotators = array();
      
          /**
           * @var Rotator $mainRotator
           *
           * @ORM\OneToOne(targetEntity="Rotator")
           * @ORM\JoinColumn(name="mainRotatorId", referencedColumnName="id")
           */
          private $mainRotator;
      
          /**
           * @var int $mainRotatorId
           *
           * @ORM\Column(name="mainRotatorId", type="integer", nullable="true")
           */
          private $mainRotatorId;
      }
      
       
      class Rotator
      {
          /**
           * @var integer $id
           *
           * @ORM\Column(name="id", type="integer")
           * @ORM\Id
           * @ORM\GeneratedValue(strategy="AUTO")
           */
          private $id;
      
          /**
           * @var Zone $zone
           *
           * @ORM\ManyToOne(targetEntity="Zone")
           * @ORM\JoinColumn(name="zoneId", referencedColumnName="id")
           */
          private $zone;
      
          /**
           * @var int $zoneId
           *
           * @ORM\Column(name="zoneId", type="integer")
           */
          private $zoneId;
      }
      

      When I delete only Zone - calculator works fine. But it fails if I delete entity Site, that relates to Zone as one-to-many (and have a lot of other raltions, so I don't write it here).

      As I look through the code, I see CommitOrderCalculator doesn't distiguish mandatory many-to-one relation from optional one-to-one one.

      PS this code hadn't been changed since 2.0, so this bug should be reproducable for master.

        Activity

        miptpatriot created issue -
        miptpatriot made changes -
        Field Original Value New Value
        Description I have 2 classes. Zone and Rotator.
        Zone relates to Rotator as One-to-Many. And Zone COULD realte to Rotator as One-to-One. Here is code snippet:

        class Zone
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @ORM\OneToMany(targetEntity="Rotator", mappedBy="zone", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
             * @ORM\OrderBy({"id" = "ASC"})
             */
            private $rotators = array();

            /**
             * @var Rotator $mainRotator
             *
             * @ORM\OneToOne(targetEntity="Rotator", inversedBy="zone")
             * @ORM\JoinColumn(name="mainRotatorId", referencedColumnName="id")
             */
            private $mainRotator;

            /**
             * @var int $mainRotatorId
             *
             * @ORM\Column(name="mainRotatorId", type="integer", nullable="true")
             */
            private $mainRotatorId;
        }

        class Rotator
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @var Zone $zone
             *
             * @ORM\ManyToOne(targetEntity="Zone")
             * @ORM\JoinColumn(name="zoneId", referencedColumnName="id")
             */
            private $zone;

            /**
             * @var int $zoneId
             *
             * @ORM\Column(name="zoneId", type="integer")
             */
            private $zoneId;
        }

        When I delete only Zone - calculator works fine. But it fails if I delete entity Site, that relates to Zone as one-to-many (and have a lot of other raltions, so I don't write it here).

        As I look through the code, I see CommitOrderCalculator doesn't distiguish mandatory many-to-one relation from optional one-to-one one.

        PS this code hadn't been changed since 2.0, so this bug should be reproducable for master.
        I have 2 classes. Zone and Rotator.
        Zone relates to Rotator as One-to-Many. And Zone COULD realte to Rotator as One-to-One. Here is code snippet:

        {noformat}
        class Zone
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @ORM\OneToMany(targetEntity="Rotator", mappedBy="zone", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
             * @ORM\OrderBy({"id" = "ASC"})
             */
            private $rotators = array();

            /**
             * @var Rotator $mainRotator
             *
             * @ORM\OneToOne(targetEntity="Rotator", inversedBy="zone")
             * @ORM\JoinColumn(name="mainRotatorId", referencedColumnName="id")
             */
            private $mainRotator;

            /**
             * @var int $mainRotatorId
             *
             * @ORM\Column(name="mainRotatorId", type="integer", nullable="true")
             */
            private $mainRotatorId;
        }
        {noformat}

        {noformat}
        class Rotator
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @var Zone $zone
             *
             * @ORM\ManyToOne(targetEntity="Zone")
             * @ORM\JoinColumn(name="zoneId", referencedColumnName="id")
             */
            private $zone;

            /**
             * @var int $zoneId
             *
             * @ORM\Column(name="zoneId", type="integer")
             */
            private $zoneId;
        }
        {noformat}

        When I delete only Zone - calculator works fine. But it fails if I delete entity Site, that relates to Zone as one-to-many (and have a lot of other raltions, so I don't write it here).

        As I look through the code, I see CommitOrderCalculator doesn't distiguish mandatory many-to-one relation from optional one-to-one one.

        PS this code hadn't been changed since 2.0, so this bug should be reproducable for master.
        miptpatriot made changes -
        Comment [ rotator class again (parser brokes it)

        {noformat}
        class Rotator
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @var Zone $zone
             *
             * @ORM\ManyToOne(targetEntity="Zone")
             * @ORM\JoinColumn(name="zoneId", referencedColumnName="id")
             */
            private $zone;

            /**
             * @var int $zoneId
             *
             * @ORM\Column(name="zoneId", type="integer")
             */
            private $zoneId;
        }
        {noformat} ]
        miptpatriot made changes -
        Description I have 2 classes. Zone and Rotator.
        Zone relates to Rotator as One-to-Many. And Zone COULD realte to Rotator as One-to-One. Here is code snippet:

        {noformat}
        class Zone
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @ORM\OneToMany(targetEntity="Rotator", mappedBy="zone", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
             * @ORM\OrderBy({"id" = "ASC"})
             */
            private $rotators = array();

            /**
             * @var Rotator $mainRotator
             *
             * @ORM\OneToOne(targetEntity="Rotator", inversedBy="zone")
             * @ORM\JoinColumn(name="mainRotatorId", referencedColumnName="id")
             */
            private $mainRotator;

            /**
             * @var int $mainRotatorId
             *
             * @ORM\Column(name="mainRotatorId", type="integer", nullable="true")
             */
            private $mainRotatorId;
        }
        {noformat}

        {noformat}
        class Rotator
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @var Zone $zone
             *
             * @ORM\ManyToOne(targetEntity="Zone")
             * @ORM\JoinColumn(name="zoneId", referencedColumnName="id")
             */
            private $zone;

            /**
             * @var int $zoneId
             *
             * @ORM\Column(name="zoneId", type="integer")
             */
            private $zoneId;
        }
        {noformat}

        When I delete only Zone - calculator works fine. But it fails if I delete entity Site, that relates to Zone as one-to-many (and have a lot of other raltions, so I don't write it here).

        As I look through the code, I see CommitOrderCalculator doesn't distiguish mandatory many-to-one relation from optional one-to-one one.

        PS this code hadn't been changed since 2.0, so this bug should be reproducable for master.
        I have 2 classes. Zone and Rotator.
        Zone relates to Rotator as One-to-Many. And Zone COULD realte to Rotator as One-to-One. Here is code snippet:

        {noformat}
        class Zone
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @ORM\OneToMany(targetEntity="Rotator", mappedBy="zone", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
             * @ORM\OrderBy({"id" = "ASC"})
             */
            private $rotators = array();

            /**
             * @var Rotator $mainRotator
             *
             * @ORM\OneToOne(targetEntity="Rotator")
             * @ORM\JoinColumn(name="mainRotatorId", referencedColumnName="id")
             */
            private $mainRotator;

            /**
             * @var int $mainRotatorId
             *
             * @ORM\Column(name="mainRotatorId", type="integer", nullable="true")
             */
            private $mainRotatorId;
        }
        {noformat}

        {noformat}
        class Rotator
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;

            /**
             * @var Zone $zone
             *
             * @ORM\ManyToOne(targetEntity="Zone")
             * @ORM\JoinColumn(name="zoneId", referencedColumnName="id")
             */
            private $zone;

            /**
             * @var int $zoneId
             *
             * @ORM\Column(name="zoneId", type="integer")
             */
            private $zoneId;
        }
        {noformat}

        When I delete only Zone - calculator works fine. But it fails if I delete entity Site, that relates to Zone as one-to-many (and have a lot of other raltions, so I don't write it here).

        As I look through the code, I see CommitOrderCalculator doesn't distiguish mandatory many-to-one relation from optional one-to-one one.

        PS this code hadn't been changed since 2.0, so this bug should be reproducable for master.
        Guilherme Blanco made changes -
        Status Open [ 1 ] Awaiting Feedback [ 10000 ]
        Hide
        Guilherme Blanco added a comment -

        Your issue is because you have $zone and $zoneId pointing both to an association AND to a field.
        Remove the $zoneId field (you can grab it by many different ways) and your issue should be solved.

        Show
        Guilherme Blanco added a comment - Your issue is because you have $zone and $zoneId pointing both to an association AND to a field. Remove the $zoneId field (you can grab it by many different ways) and your issue should be solved.
        made changes -
        Status Awaiting Feedback [ 10000 ] In Progress [ 3 ]
        Hide
        Benjamin Eberlei added a comment -

        You mention Site? Where is this entity, please make a snippet available as well.

        And then, can you show some example object graph that you are trying to delete? This case is data dependent.

        Show
        Benjamin Eberlei added a comment - You mention Site? Where is this entity, please make a snippet available as well. And then, can you show some example object graph that you are trying to delete? This case is data dependent.
        Hide
        miptpatriot added a comment - - edited
        class Site
        {
            /**
             * @var integer $id
             *
             * @ORM\Column(name="id", type="integer")
             * @ORM\Id
             * @ORM\GeneratedValue(strategy="AUTO")
             */
            private $id;
        
            /**
             * @var \Doctrine\Common\Collections\Collection|SiteAlias[]
             * @ORM\OneToMany(targetEntity="SiteAlias", mappedBy="site", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
             */
            private $aliases;
        
            /**
             * @ORM\OneToMany(targetEntity="Zone", mappedBy="site", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
             */
            private $zones;
        
            /**
             * @ORM\OneToMany(targetEntity="Banner", mappedBy="site", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
             */
            private $banners;
        
            /**
             * @var integer
             *
             * @ORM\Column(name="user_id", type="integer")
             */
            private $user_id;
        
            /**
             * @var \Iw\UserBundle\Entity\User
             *
             * @ORM\ManyToOne(targetEntity="\Iw\UserBundle\Entity\User")
             * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
             */
            private $user;
        }
        
        Show
        miptpatriot added a comment - - edited class Site { /** * @var integer $id * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @var \Doctrine\Common\Collections\Collection|SiteAlias[] * @ORM\OneToMany(targetEntity="SiteAlias", mappedBy="site", cascade={"persist", "remove", "merge"}, orphanRemoval=true) */ private $aliases; /** * @ORM\OneToMany(targetEntity="Zone", mappedBy="site", cascade={"persist", "remove", "merge"}, orphanRemoval=true) */ private $zones; /** * @ORM\OneToMany(targetEntity="Banner", mappedBy="site", cascade={"persist", "remove", "merge"}, orphanRemoval=true) */ private $banners; /** * @var integer * * @ORM\Column(name="user_id", type="integer") */ private $user_id; /** * @var \Iw\UserBundle\Entity\User * * @ORM\ManyToOne(targetEntity="\Iw\UserBundle\Entity\User") * @ORM\JoinColumn(name="user_id", referencedColumnName="id") */ private $user; }
        Hide
        miptpatriot added a comment -

        Is there any fast way to debug output object graph? Like execute print_r somewhere in code.

        Show
        miptpatriot added a comment - Is there any fast way to debug output object graph? Like execute print_r somewhere in code.
        Hide
        Ivan Borzenkov added a comment -

        Confirmed
        removing ID fields not work

        i fix this whis add

        • @ORM\JoinColumn(onDelete="cascade")
          to child Entity ManyToOne link

        OnetoOne Unidirectinal set child after of parent
        but OneToMany set set child before of parent (how need)

        Show
        Ivan Borzenkov added a comment - Confirmed removing ID fields not work i fix this whis add @ORM\JoinColumn(onDelete="cascade") to child Entity ManyToOne link OnetoOne Unidirectinal set child after of parent but OneToMany set set child before of parent (how need)
        Hide
        Benjamin Eberlei added a comment -

        I finally get this issue, and bidirecitonal foreign keys are only deletable with "onDelete=CASCADE", there is absolutely no way for the CommitOrderCalculator to fix this.

        Show
        Benjamin Eberlei added a comment - I finally get this issue, and bidirecitonal foreign keys are only deletable with "onDelete=CASCADE", there is absolutely no way for the CommitOrderCalculator to fix this.
        Benjamin Eberlei made changes -
        Status In Progress [ 3 ] Resolved [ 5 ]
        Resolution Invalid [ 6 ]

        This list may be incomplete, as errors occurred whilst retrieving source from linked applications:

        • Request to http://www.doctrine-project.org/fisheye/ failed: Error in remote call to 'FishEye 0 (http://www.doctrine-project.org/fisheye/)' (http://www.doctrine-project.org/fisheye) [AbstractRestCommand{path='/rest-service-fe/search-v1/crossRepositoryQuery', params={query=DDC-1968, expand=changesets[0:20].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            miptpatriot
          • Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: