Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-2383

Foreign relations on primary keys don't work on more than two entities (like Foo<>Bar<>Baz)

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Can't Fix
    • Affects Version/s: 2.3, 2.4
    • Fix Version/s: None
    • Component/s: ORM

      Description

      I'm trying to accomplish something like this:
      http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

      For two entities (Foo<>Bar) it works as expected but adding another entity related to Bar (so it's Foo<>Bar<>Baz) ends up with this error:

      Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'The column id must be mapped to a field in class Entity\Bar since it is referenced by a join column of another class.' in C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\MappingException.php:203
      Stack trace:
      #0 C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php(734): Doctrine\ORM\Mapping\MappingException::joinColumnMustPointToMappedField('Entity\Bar', 'id')
      #1 C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(2509): Doctrine\ORM\Persisters\BasicEntityPersister->loadOneToOneEntity(Array, Object(Entity\Bar))
      #2 C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php(245): Doctrine\ORM\UnitOfWork->createEntity('Entity\Bar', Array, Array)
      #3 C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php(424): Doctrine\ORM\Internal\Hydration\Ob in C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\MappingException.php on line 203
      

      This error appears when there are some records in the database and I want to query for example all Foos.

      My entites look like this:

      //Entity/Foo.php
      
      /** @Entity @Table(name="foos") */
      class Foo
      {
          /** @Id @Column(type="integer") @GeneratedValue */
          protected $id;
      
          /** @OneToOne(targetEntity="Bar", mappedBy="foo") */
          protected $bar;
      
          public function getId()
          {
              return $this->id;
          }
      
          public function getBar()
          {
              return $this->bar;
          }
      
          public function setBar($bar)
          {
              $bar->setFoo($this);
              $this->bar = $bar;
          }
      }
      
      //Entity/Bar.php
      
      /** @Entity @Table(name="bars") */
      class Bar
      {
          /** @Id @OneToOne(targetEntity="Foo", inversedBy="bar")
           * @JoinColumn(name="id", referencedColumnName="id") */
          protected $foo;
      
          /** @OneToOne(targetEntity="Baz", mappedBy="bar") */
          protected $baz;
      
          public function __construct($foo)
          {
              $this->foo = $foo;
          }
      
          public function getId()
          {
              return $this->getFoo()->getId();
          }
      
          public function getFoo()
          {
              return $this->foo;
          }
      
          public function setFoo($foo)
          {
              $this->foo = $foo;
          }
      
          public function getBaz()
          {
              return $this->baz;
          }
      
          public function setBaz($baz)
          {
              $bar->setBar($this);
              $this->baz = $baz;
          }
      }
      
      //Entity/Baz.php
      
      /** @Entity @Table(name="bazes") */
      class Baz
      {
          /** @Id @OneToOne(targetEntity="Bar", inversedBy="baz")
           * @JoinColumn(name="id", referencedColumnName="id") */
          protected $bar;
      
          public function __construct($bar)
          {
              $this->bar = $bar;
          }
      
          public function getId()
          {
              return $this->getBar()->getId();
          }
      
          public function getBar()
          {
              return $this->bar;
          }
      
          public function setBar($bar)
          {
              $this->bar = $bar;
          }
      }
      

      And fails on

      $fooRepository = $em->getRepository('Entity\Foo');
      $foos = $fooRepository->findAll();
      
      1. DDC2383Test.php
        3 kB
        Jacek Jędrzejewski

        Activity

        Jacek Jędrzejewski created issue -
        Jacek Jędrzejewski made changes -
        Field Original Value New Value
        Summary Foo<>Bar<>Baz - primary key and Foo<>Bar<>Baz - foreign relations on primary keys
        Jacek Jędrzejewski made changes -
        Description I'm trying to accomplish something like this:
        http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

        For two entities (Foo<>Bar) it works as expected but adding another entity related to Bar (so it's Foo<>Bar<>Baz) ends up with this error:

        {code}
        [Doctrine\ORM\ORMException]
        Column name `id` referenced for relation from Entity\Baz towards Entity\Bar does not exist.
        {/code}

        My entites look like this:

        {code:php}
        //Entity/Foo.php

        /** @Entity @Table(name="foos") */
        class Foo
        {
            /** @Id @Column(type="integer") @GeneratedValue */
            protected $id;

            /** @OneToOne(targetEntity="Bar", mappedBy="foo") */
            protected $bar;

            public function getId()
            {
                return $this->id;
            }

            public function getBar()
            {
                return $this->bar;
            }

            public function setBar($bar)
            {
                $bar->setFoo($this);
                $this->bar = $bar;
            }
        }

        //Entity/Bar.php

        /** @Entity @Table(name="bars") */
        class Bar
        {
            /** @Id @OneToOne(targetEntity="Foo", inversedBy="bar") */
            protected $foo;

            /** @OneToOne(targetEntity="Baz", mappedBy="bar") */
            protected $baz;

            public function __construct($foo)
            {
                $this->foo = $foo;
            }

            public function getId()
            {
                return $this->getFoo()->getId();
            }

            public function getFoo()
            {
                return $this->foo;
            }

            public function setFoo($foo)
            {
                $this->foo = $foo;
            }

            public function getBaz()
            {
                return $this->baz;
            }

            public function setBaz($baz)
            {
                $bar->setBar($this);
                $this->baz = $baz;
            }
        }

        //Entity/Baz.php

        /** @Entity @Table(name="bazes") */
        class Baz
        {
            /** @Id @OneToOne(targetEntity="Bar", inversedBy="baz") */
            protected $bar;

            public function __construct($bar)
            {
                $this->bar = $bar;
            }

            public function getId()
            {
                return $this->getBar()->getId();
            }

            public function getBar()
            {
                return $this->bar;
            }

            public function setBar($bar)
            {
                $this->bar = $bar;
            }
        }
        {/code}
        I'm trying to accomplish something like this:
        http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

        For two entities (Foo<>Bar) it works as expected but adding another entity related to Bar (so it's Foo<>Bar<>Baz) ends up with this error:

        {code}
        [Doctrine\ORM\ORMException]
        Column name `id` referenced for relation from Entity\Baz towards Entity\Bar does not exist.
        {code}

        My entites look like this:

        {code}
        //Entity/Foo.php

        /** @Entity @Table(name="foos") */
        class Foo
        {
            /** @Id @Column(type="integer") @GeneratedValue */
            protected $id;

            /** @OneToOne(targetEntity="Bar", mappedBy="foo") */
            protected $bar;

            public function getId()
            {
                return $this->id;
            }

            public function getBar()
            {
                return $this->bar;
            }

            public function setBar($bar)
            {
                $bar->setFoo($this);
                $this->bar = $bar;
            }
        }

        //Entity/Bar.php

        /** @Entity @Table(name="bars") */
        class Bar
        {
            /** @Id @OneToOne(targetEntity="Foo", inversedBy="bar") */
            protected $foo;

            /** @OneToOne(targetEntity="Baz", mappedBy="bar") */
            protected $baz;

            public function __construct($foo)
            {
                $this->foo = $foo;
            }

            public function getId()
            {
                return $this->getFoo()->getId();
            }

            public function getFoo()
            {
                return $this->foo;
            }

            public function setFoo($foo)
            {
                $this->foo = $foo;
            }

            public function getBaz()
            {
                return $this->baz;
            }

            public function setBaz($baz)
            {
                $bar->setBar($this);
                $this->baz = $baz;
            }
        }

        //Entity/Baz.php

        /** @Entity @Table(name="bazes") */
        class Baz
        {
            /** @Id @OneToOne(targetEntity="Bar", inversedBy="baz") */
            protected $bar;

            public function __construct($bar)
            {
                $this->bar = $bar;
            }

            public function getId()
            {
                return $this->getBar()->getId();
            }

            public function getBar()
            {
                return $this->bar;
            }

            public function setBar($bar)
            {
                $this->bar = $bar;
            }
        }
        {code}
        Jacek Jędrzejewski made changes -
        Summary Foo<>Bar<>Baz - foreign relations on primary keys Foreign relations on primary keys don't work on more than two entities (like Foo<>Bar<>Baz)
        Jacek Jędrzejewski made changes -
        Description I'm trying to accomplish something like this:
        http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

        For two entities (Foo<>Bar) it works as expected but adding another entity related to Bar (so it's Foo<>Bar<>Baz) ends up with this error:

        {code}
        [Doctrine\ORM\ORMException]
        Column name `id` referenced for relation from Entity\Baz towards Entity\Bar does not exist.
        {code}

        My entites look like this:

        {code}
        //Entity/Foo.php

        /** @Entity @Table(name="foos") */
        class Foo
        {
            /** @Id @Column(type="integer") @GeneratedValue */
            protected $id;

            /** @OneToOne(targetEntity="Bar", mappedBy="foo") */
            protected $bar;

            public function getId()
            {
                return $this->id;
            }

            public function getBar()
            {
                return $this->bar;
            }

            public function setBar($bar)
            {
                $bar->setFoo($this);
                $this->bar = $bar;
            }
        }

        //Entity/Bar.php

        /** @Entity @Table(name="bars") */
        class Bar
        {
            /** @Id @OneToOne(targetEntity="Foo", inversedBy="bar") */
            protected $foo;

            /** @OneToOne(targetEntity="Baz", mappedBy="bar") */
            protected $baz;

            public function __construct($foo)
            {
                $this->foo = $foo;
            }

            public function getId()
            {
                return $this->getFoo()->getId();
            }

            public function getFoo()
            {
                return $this->foo;
            }

            public function setFoo($foo)
            {
                $this->foo = $foo;
            }

            public function getBaz()
            {
                return $this->baz;
            }

            public function setBaz($baz)
            {
                $bar->setBar($this);
                $this->baz = $baz;
            }
        }

        //Entity/Baz.php

        /** @Entity @Table(name="bazes") */
        class Baz
        {
            /** @Id @OneToOne(targetEntity="Bar", inversedBy="baz") */
            protected $bar;

            public function __construct($bar)
            {
                $this->bar = $bar;
            }

            public function getId()
            {
                return $this->getBar()->getId();
            }

            public function getBar()
            {
                return $this->bar;
            }

            public function setBar($bar)
            {
                $this->bar = $bar;
            }
        }
        {code}
        I'm trying to accomplish something like this:
        http://docs.doctrine-project.org/en/latest/tutorials/composite-primary-keys.html#use-case-2-simple-derived-identity

        For two entities (Foo<>Bar) it works as expected but adding another entity related to Bar (so it's Foo<>Bar<>Baz) ends up with this error:

        {code}
        Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'The column id must be mapped to a field in class Entity\Bar since it is referenced by a join column of another class.' in C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\MappingException.php:203
        Stack trace:
        #0 C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Persisters\BasicEntityPersister.php(734): Doctrine\ORM\Mapping\MappingException::joinColumnMustPointToMappedField('Entity\Bar', 'id')
        #1 C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\UnitOfWork.php(2509): Doctrine\ORM\Persisters\BasicEntityPersister->loadOneToOneEntity(Array, Object(Entity\Bar))
        #2 C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php(245): Doctrine\ORM\UnitOfWork->createEntity('Entity\Bar', Array, Array)
        #3 C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Internal\Hydration\ObjectHydrator.php(424): Doctrine\ORM\Internal\Hydration\Ob in C:\...\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\MappingException.php on line 203
        {code}

        This error appears when there are some records in the database and I want to query for example all Foos.

        My entites look like this:

        {code}
        //Entity/Foo.php

        /** @Entity @Table(name="foos") */
        class Foo
        {
            /** @Id @Column(type="integer") @GeneratedValue */
            protected $id;

            /** @OneToOne(targetEntity="Bar", mappedBy="foo") */
            protected $bar;

            public function getId()
            {
                return $this->id;
            }

            public function getBar()
            {
                return $this->bar;
            }

            public function setBar($bar)
            {
                $bar->setFoo($this);
                $this->bar = $bar;
            }
        }

        //Entity/Bar.php

        /** @Entity @Table(name="bars") */
        class Bar
        {
            /** @Id @OneToOne(targetEntity="Foo", inversedBy="bar")
             * @JoinColumn(name="id", referencedColumnName="id") */
            protected $foo;

            /** @OneToOne(targetEntity="Baz", mappedBy="bar") */
            protected $baz;

            public function __construct($foo)
            {
                $this->foo = $foo;
            }

            public function getId()
            {
                return $this->getFoo()->getId();
            }

            public function getFoo()
            {
                return $this->foo;
            }

            public function setFoo($foo)
            {
                $this->foo = $foo;
            }

            public function getBaz()
            {
                return $this->baz;
            }

            public function setBaz($baz)
            {
                $bar->setBar($this);
                $this->baz = $baz;
            }
        }

        //Entity/Baz.php

        /** @Entity @Table(name="bazes") */
        class Baz
        {
            /** @Id @OneToOne(targetEntity="Bar", inversedBy="baz")
             * @JoinColumn(name="id", referencedColumnName="id") */
            protected $bar;

            public function __construct($bar)
            {
                $this->bar = $bar;
            }

            public function getId()
            {
                return $this->getBar()->getId();
            }

            public function getBar()
            {
                return $this->bar;
            }

            public function setBar($bar)
            {
                $this->bar = $bar;
            }
        }
        {code}

        And fails on

        {code}
        $fooRepository = $em->getRepository('Entity\Foo');
        $foos = $fooRepository->findAll();
        {code}
        Jacek Jędrzejewski made changes -
        Labels mapping relations hydration mapping relations
        Jacek Jędrzejewski made changes -
        Attachment DDC2383Test.php [ 11520 ]
        Benjamin Eberlei made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Can't Fix [ 7 ]

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Jacek Jędrzejewski
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: