Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-1970

DiscriminatorMap recursion when using self-reference

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.3
    • Fix Version/s: None
    • Component/s: ORM
    • Security Level: All
    • Labels:
      None

      Description

      I've ran into a problem with self-referencing entity. When fetching an entity, recursion occurs, fetching every related entity defined by ManyToOne relation
      (in this example $sponsor), ignoring LAZY or EXTRA_LAZY fetch mode - it executes numerous queries.

      /**
       * @ORM\Entity(repositoryClass="Acme\Bundle\UserBundle\Entity\Repository\UserRepository")
       * @ORM\Table(name="f_user")
       * @ORM\InheritanceType("JOINED")
       * @ORM\DiscriminatorColumn(name="type", type="string")
       * @ORM\DiscriminatorMap({"user_person" = "UserPerson", "user_company" = "UserCompany"})
       */
      abstract class UserBase extends FOSUser
      
      /* .... */
      
          /**
           * @var UserBase
           *
           * @ORM\OneToMany(targetEntity="UserBase", mappedBy="sponsor")
           */
          protected $referrals;
      
          /**
           * @ORM\ManyToOne(targetEntity="UserBase", inversedBy="referrals")
           * @ORM\JoinColumn(name="sponsor_id", referencedColumnName="id")
           */
          protected $sponsor;
      
      

        Activity

        Krzysztof Kolasiak created issue -
        Krzysztof Kolasiak made changes -
        Field Original Value New Value
        Description I've ran into a problem with self-referencing entity. When fetching an entity, recursion occurs, fetching every related entity defined by ManyToOne relation.
        (in this example $sponsor), ignoring LAZY or EXTRA_LAZY fetch mode.

        {code}
        /**
         * @ORM\Entity(repositoryClass="Acme\Bundle\UserBundle\Entity\Repository\UserRepository")
         * @ORM\Table(name="f_user")
         * @ORM\InheritanceType("JOINED")
         * @ORM\DiscriminatorColumn(name="type", type="string")
         * @ORM\DiscriminatorMap({"user_person" = "UserPerson", "user_company" = "UserCompany"})
         */
        abstract class UserBase extends FOSUser

        /* .... */

            /**
             * @var UserBase
             *
             * @ORM\OneToMany(targetEntity="UserBase", mappedBy="sponsor")
             */
            protected $referrals;

            /**
             * @ORM\ManyToOne(targetEntity="UserBase", inversedBy="referrals")
             * @ORM\JoinColumn(name="sponsor_id", referencedColumnName="id")
             */
            protected $sponsor;

        {/code}
        I've ran into a problem with self-referencing entity. When fetching an entity, recursion occurs, fetching every related entity defined by ManyToOne relation.
        (in this example $sponsor), ignoring LAZY or EXTRA_LAZY fetch mode.

        {code}
        /**
         * @ORM\Entity(repositoryClass="Acme\Bundle\UserBundle\Entity\Repository\UserRepository")
         * @ORM\Table(name="f_user")
         * @ORM\InheritanceType("JOINED")
         * @ORM\DiscriminatorColumn(name="type", type="string")
         * @ORM\DiscriminatorMap({"user_person" = "UserPerson", "user_company" = "UserCompany"})
         */
        abstract class UserBase extends FOSUser

        /* .... */

            /**
             * @var UserBase
             *
             * @ORM\OneToMany(targetEntity="UserBase", mappedBy="sponsor")
             */
            protected $referrals;

            /**
             * @ORM\ManyToOne(targetEntity="UserBase", inversedBy="referrals")
             * @ORM\JoinColumn(name="sponsor_id", referencedColumnName="id")
             */
            protected $sponsor;

        {code}
        Krzysztof Kolasiak made changes -
        Description I've ran into a problem with self-referencing entity. When fetching an entity, recursion occurs, fetching every related entity defined by ManyToOne relation.
        (in this example $sponsor), ignoring LAZY or EXTRA_LAZY fetch mode.

        {code}
        /**
         * @ORM\Entity(repositoryClass="Acme\Bundle\UserBundle\Entity\Repository\UserRepository")
         * @ORM\Table(name="f_user")
         * @ORM\InheritanceType("JOINED")
         * @ORM\DiscriminatorColumn(name="type", type="string")
         * @ORM\DiscriminatorMap({"user_person" = "UserPerson", "user_company" = "UserCompany"})
         */
        abstract class UserBase extends FOSUser

        /* .... */

            /**
             * @var UserBase
             *
             * @ORM\OneToMany(targetEntity="UserBase", mappedBy="sponsor")
             */
            protected $referrals;

            /**
             * @ORM\ManyToOne(targetEntity="UserBase", inversedBy="referrals")
             * @ORM\JoinColumn(name="sponsor_id", referencedColumnName="id")
             */
            protected $sponsor;

        {code}
        I've ran into a problem with self-referencing entity. When fetching an entity, recursion occurs, fetching every related entity defined by ManyToOne relation
        (in this example $sponsor), ignoring LAZY or EXTRA_LAZY fetch mode - it executes numerous queries.

        {code}
        /**
         * @ORM\Entity(repositoryClass="Acme\Bundle\UserBundle\Entity\Repository\UserRepository")
         * @ORM\Table(name="f_user")
         * @ORM\InheritanceType("JOINED")
         * @ORM\DiscriminatorColumn(name="type", type="string")
         * @ORM\DiscriminatorMap({"user_person" = "UserPerson", "user_company" = "UserCompany"})
         */
        abstract class UserBase extends FOSUser

        /* .... */

            /**
             * @var UserBase
             *
             * @ORM\OneToMany(targetEntity="UserBase", mappedBy="sponsor")
             */
            protected $referrals;

            /**
             * @ORM\ManyToOne(targetEntity="UserBase", inversedBy="referrals")
             * @ORM\JoinColumn(name="sponsor_id", referencedColumnName="id")
             */
            protected $sponsor;

        {code}
        Alexander made changes -
        Issue Type Bug [ 1 ] New Feature [ 2 ]
        Hide
        Alexander added a comment -

        I have changed this into a feature request because you have hit the limitations of using inheritance and self referencing entities.

        Doctrine2 cannot currently lazy load UserBase#$sponsor because we don't know which proxy we have to insert. It can either be UserPerson or UserCompany. In order to know this Doctrine2 has to query the actual object to determine its type. The current strategy is then to load the actual entity because we have all data anyway.

        In order to implement this feature we need to insert a proxy instead of the actual entity. If we do that there should be no recursion happening.

        Show
        Alexander added a comment - I have changed this into a feature request because you have hit the limitations of using inheritance and self referencing entities. Doctrine2 cannot currently lazy load UserBase#$sponsor because we don't know which proxy we have to insert. It can either be UserPerson or UserCompany. In order to know this Doctrine2 has to query the actual object to determine its type. The current strategy is then to load the actual entity because we have all data anyway. In order to implement this feature we need to insert a proxy instead of the actual entity. If we do that there should be no recursion happening.
        Hide
        Marco Pivetta added a comment -

        Reduced priority

        Show
        Marco Pivetta added a comment - Reduced priority
        Marco Pivetta made changes -
        Priority Critical [ 2 ] Major [ 3 ]
        Hide
        Prathap added a comment -

        It'd be great if this is a configurable option.

        Show
        Prathap added a comment - It'd be great if this is a configurable option.
        Hide
        Kevin Bond added a comment -

        I have also run into this.

        Show
        Kevin Bond added a comment - I have also run into this.

        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-1970, expand=changesets[0:20].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)

          People

          • Assignee:
            Benjamin Eberlei
            Reporter:
            Krzysztof Kolasiak
          • Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated: