Doctrine MongoDB ODM
  1. Doctrine MongoDB ODM
  2. MODM-139

[PATCH] @ReferenceMany with no referenceMapping cannot handle DBRef in all / in queries

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.0.0BETA3
    • Fix Version/s: None
    • Component/s: Document Manager
    • Labels:
      None
    • Environment:
      Linux, PHP 5.3

      Description

      I have thoose examples :

      /** @Document 
       * @InheritanceType("SINGLE_COLLECTION")
       * @DiscriminatorField(fieldName="type")
       * @DiscriminatorMap({"Test\Product"="Product", "Test\Year"="Year"})
      */
      Attributes {
         /** @Id */
         protected $_id;
      }
      
      /** @Document */
      class Product extends Attributes {}
      
      /** @Document */
      class Year extends Attributes {}
      
      /**
       * Classe de base pour les différents contenus
       * @Document
       * @InheritanceType("SINGLE_COLLECTION")
       * @DiscriminatorField(fieldName="type")
       * @DiscriminatorMap({"Test\Document"="Document", "Test\Infos"="Infos"})  
       */
      class Content
      {
         /** protected $_id */
          /** @ReferenceMany */
          protected $_attributes;
      }
      

      And the querying stuff

      //and the query : 
      $queryBuilder = $dm->createQueryBuilder('Test\DOcument');
      //...
      $attribute1Ref = $dm->createDBRef($attribute1Object);
      $attribute2Ref = $dm->createDBRef($attribute2Object);
      $queryBuilder->field('_attributes')->all(array($attribute1Ref, $attribute2Ref));
      $queryBuilder->getQuery()->execute();//Won't work as the generated query won't specify the "_doctrine_class_name" value.
      

      Proposed patch in DocumentManager :

          /**
           * Returns a DBRef array for the supplied document.
           *
           * @param mixed $document A document object
           * @param array $referenceMapping Mapping for the field the references the document
           *
           * @return array A DBRef array
           */
          public function createDBRef($document, array $referenceMapping = null)
          {
              $className = get_class($document);
              $class = $this->getClassMetadata($className);
              $id = $this->unitOfWork->getDocumentIdentifier($document);
      
              $dbRef = array(
                  $this->cmd . 'ref' => $class->getCollection(),
                  $this->cmd . 'id'  => $class->getDatabaseIdentifierValue($id),
                  $this->cmd . 'db'  => $this->getDocumentDatabase($className)->getName()
              );
      
              // add a discriminator value if the referenced document is not mapped explicitely to a targetDocument
              if ($referenceMapping && ! isset($referenceMapping['targetDocument'])) {
                  $discriminatorField = isset($referenceMapping['discriminatorField']) ? $referenceMapping['discriminatorField'] : '_doctrine_class_name';
                  $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->getName(), $referenceMapping['discriminatorMap']) : $class->getName();
                  $dbRef[$discriminatorField] = $discriminatorValue;
      +        }  elseif ($referenceMapping === null) {
      +            $dbRef['_doctrine_class_name'] = $class->getName();
      +        }
              return $dbRef;
          }
      

        Activity

        Gérald Croes created issue -
        Gérald Croes made changes -
        Field Original Value New Value
        Description I have thoose examples :
        /** @Document
         * @InheritanceType("SINGLE_COLLECTION")
         * @DiscriminatorField(fieldName="type")
         * @DiscriminatorMap({"Test\Product"="Product", "Test\Year"="Year"})
        */
        Attributes {
           /** @Id */
           protected $_id;
        }

        /** @Document */
        class Product extends Attributes {}

        /** @Document */
        class Year extends Attributes {}

        And the Content class :
        /**
         * Classe de base pour les différents contenus
         * @Document
         * @InheritanceType("SINGLE_COLLECTION")
         * @DiscriminatorField(fieldName="type")
         * @DiscriminatorMap({"Test\Document"="Document", "Test\Infos"="Infos"})
         */
        class Content
        {
           /** protected $_id */
            /** @ReferenceMany */
            protected $_attributes;
        }

        //and the query :
        $queryBuilder = $dm->createQueryBuilder('Test\DOcument');
        //...
        $attribute1Ref = $dm->createDBRef($attribute1Object);
        $attribute2Ref = $dm->createDBRef($attribute2Object);
        $queryBuilder->field('_attributes')->all(array($attribute1Ref, $attribute2Ref));
        $queryBuilder->getQuery()->execute();//Won't work as the generated query won't specify the "_doctrine_class_name" value.

        Proposed patch in DocumentManager :
            /**
             * Returns a DBRef array for the supplied document.
             *
             * @param mixed $document A document object
             * @param array $referenceMapping Mapping for the field the references the document
             *
             * @return array A DBRef array
             */
            public function createDBRef($document, array $referenceMapping = null)
            {
                $className = get_class($document);
                $class = $this->getClassMetadata($className);
                $id = $this->unitOfWork->getDocumentIdentifier($document);

                $dbRef = array(
                    $this->cmd . 'ref' => $class->getCollection(),
                    $this->cmd . 'id' => $class->getDatabaseIdentifierValue($id),
                    $this->cmd . 'db' => $this->getDocumentDatabase($className)->getName()
                );

                // add a discriminator value if the referenced document is not mapped explicitely to a targetDocument
                if ($referenceMapping && ! isset($referenceMapping['targetDocument'])) {
                    $discriminatorField = isset($referenceMapping['discriminatorField']) ? $referenceMapping['discriminatorField'] : '_doctrine_class_name';
                    $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->getName(), $referenceMapping['discriminatorMap']) : $class->getName();
                    $dbRef[$discriminatorField] = $discriminatorValue;
        + } else {
        + $dbRef['_doctrine_class_name'] = $class->getName();
        + }
                return $dbRef;
            }

        I have thoose examples :
        {noformat}
        /** @Document
         * @InheritanceType("SINGLE_COLLECTION")
         * @DiscriminatorField(fieldName="type")
         * @DiscriminatorMap({"Test\Product"="Product", "Test\Year"="Year"})
        */
        Attributes {
           /** @Id */
           protected $_id;
        }

        /** @Document */
        class Product extends Attributes {}

        /** @Document */
        class Year extends Attributes {}

        /**
         * Classe de base pour les différents contenus
         * @Document
         * @InheritanceType("SINGLE_COLLECTION")
         * @DiscriminatorField(fieldName="type")
         * @DiscriminatorMap({"Test\Document"="Document", "Test\Infos"="Infos"})
         */
        class Content
        {
           /** protected $_id */
            /** @ReferenceMany */
            protected $_attributes;
        }
        {noformat}

        And the querying stuff

        {noformat}
        //and the query :
        $queryBuilder = $dm->createQueryBuilder('Test\DOcument');
        //...
        $attribute1Ref = $dm->createDBRef($attribute1Object);
        $attribute2Ref = $dm->createDBRef($attribute2Object);
        $queryBuilder->field('_attributes')->all(array($attribute1Ref, $attribute2Ref));
        $queryBuilder->getQuery()->execute();//Won't work as the generated query won't specify the "_doctrine_class_name" value.
        {noformat}

        Proposed patch in DocumentManager :
        {noformat}
            /**
             * Returns a DBRef array for the supplied document.
             *
             * @param mixed $document A document object
             * @param array $referenceMapping Mapping for the field the references the document
             *
             * @return array A DBRef array
             */
            public function createDBRef($document, array $referenceMapping = null)
            {
                $className = get_class($document);
                $class = $this->getClassMetadata($className);
                $id = $this->unitOfWork->getDocumentIdentifier($document);

                $dbRef = array(
                    $this->cmd . 'ref' => $class->getCollection(),
                    $this->cmd . 'id' => $class->getDatabaseIdentifierValue($id),
                    $this->cmd . 'db' => $this->getDocumentDatabase($className)->getName()
                );

                // add a discriminator value if the referenced document is not mapped explicitely to a targetDocument
                if ($referenceMapping && ! isset($referenceMapping['targetDocument'])) {
                    $discriminatorField = isset($referenceMapping['discriminatorField']) ? $referenceMapping['discriminatorField'] : '_doctrine_class_name';
                    $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->getName(), $referenceMapping['discriminatorMap']) : $class->getName();
                    $dbRef[$discriminatorField] = $discriminatorValue;
        + } elseif ($referenceMapping === null) {
        + $dbRef['_doctrine_class_name'] = $class->getName();
        + }
                return $dbRef;
            }
        {noformat}

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

          People

          • Assignee:
            Jonathan H. Wage
            Reporter:
            Gérald Croes
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: