Doctrine 1
  1. Doctrine 1
  2. DC-1050

Doctrine_Relation_ForeignKey ignores ATTR_COLL_KEY attribute

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 1.2.3
    • Fix Version/s: None
    • Component/s: Attributes, Relations
    • Labels:
      None
    • Environment:
      Windows 7 64Bit
      PHP 5.3
      Symfony 1.4

      Description

      Doctrine_Relation_ForeignKey::fetchRelatedFor() executes the following code at line 70:

      $coll = $this->getTable()>getConnection()>query($dql, $id);
      $related = $coll[0];

      As you can see it accesses the first element by using index "0" in $coll and hence ignores a modified ATTR_COLL_KEY-setting, for instance:

      $this->setAttribute(Doctrine_Core::ATTR_COLL_KEY, 'id');

      Fortunately I had two models (ForeignA and ForeignB) in my project which both have an one-to-one relation to a third model (Main). That helped me finding this bug which causes the following strange behavior:

      // program 1:

      $m = new Main();
      $m->name = 'M1';
      $m->setForeignA(new ForeignA()); // has ATTR_COLL_KEY changed to 'id'
      $m->setForeignB(new ForeignB());
      $m->save();

      // program 2:

      $m = Doctrine_Core::getTable('M1')->findOneBy('name', 'M1');
      $m->getForeignA()->exists(); // false
      $m->getForeignB()->exists(); // true

      -------------------------

      The big problem about this issue is that behavior is inconsistent. If you don't split the example above into two separate programs/processes you won't have problems, since Doctrine accesses the reference which was stored when calling save().

      You will get into trouble using functional tests in Symfony. Since there is only a single process for all requests I wasn't able to reproduce a problem caused by this bug which appeared in the production environment.

      -------------------------

      Edit:

      Doctrine_Connection::queryOne() is affected as well!

      A solution is to replace

      $coll = $this->getTable()>getConnection()>query($dql, $id);
      $related = $coll[0];

      by

      $related = $this->getTable()>getConnection()>query($dql, $id)->getFirst();

      1. ForeignKey.php.patch
        0.6 kB
        Uli Hecht
      2. Form01 - Diagnóstico-12012011.doc
        140 kB
        joao guermandi
      3. Proposta do sistema de Gestão de ligas.odt
        19 kB
        joao guermandi
      4. Proposta do sistema de meio ambiente.odt
        19 kB
        joao guermandi

        Activity

        Uli Hecht created issue -
        Uli Hecht made changes -
        Field Original Value New Value
        Description Doctrine_Relation_ForeignKey::fetchRelatedFor() executes the following code at line 70:

        $coll = $this->getTable()->getConnection()->query($dql, $id);
        $related = $coll[0];

        As you can see it accesses the first element by using index "0" in $coll and hence ignores a modified ATTR_COLL_KEY-setting, for instance:

        $this->setAttribute(Doctrine_Core::ATTR_COLL_KEY, 'id');

        Fortunately I had two models (ForeignA and ForeignB) in my project which both have an one-to-one relation to a third model (Main). That helped me finding this bug which causes the following strange behavior:

        // program 1:

        $m = new Main();
        $m->name = 'M1';
        $m->setForeignA(new ForeignA()); // has ATTR_COLL_KEY changed to 'id'
        $m->setForeignB(new ForeignB());
        $m->save();

        // program 2:

        $m = Doctrine_Core::getTable('M1')->findOneBy('name', 'M1');
        $m->getForeignA()->exists(); // false
        $m->getForeignB()->exists(); // true

        -------------------------

        Now consider you run functional tests in a Symfony project: The problem disappears since you only have a single sfContext for multiple requests. I.e. this issue causes an inconsistent behavior. This is why I wrote "program 1" and "program 2" above.
        Doctrine_Relation_ForeignKey::fetchRelatedFor() executes the following code at line 70:

        $coll = $this->getTable()->getConnection()->query($dql, $id);
        $related = $coll[0];

        As you can see it accesses the first element by using index "0" in $coll and hence ignores a modified ATTR_COLL_KEY-setting, for instance:

        $this->setAttribute(Doctrine_Core::ATTR_COLL_KEY, 'id');

        Fortunately I had two models (ForeignA and ForeignB) in my project which both have an one-to-one relation to a third model (Main). That helped me finding this bug which causes the following strange behavior:

        // program 1:

        $m = new Main();
        $m->name = 'M1';
        $m->setForeignA(new ForeignA()); // has ATTR_COLL_KEY changed to 'id'
        $m->setForeignB(new ForeignB());
        $m->save();

        // program 2:

        $m = Doctrine_Core::getTable('M1')->findOneBy('name', 'M1');
        $m->getForeignA()->exists(); // false
        $m->getForeignB()->exists(); // true

        -------------------------

        The big problem about this issue is that behavior is inconsistent. If you don't split the example above into two separate programs/processes you won't have problems, since Doctrine accesses the reference which was stored when calling save().

        You will get into trouble using functional tests in Symfony. Since there is only a single process for all requests I wasn't able to reproduce a problem caused by this bug which appeared in the production environment.

        -------------------------

        Edit:

        Doctrine_Connection is affected as well.

        A solution is to replace
        Uli Hecht made changes -
        Description Doctrine_Relation_ForeignKey::fetchRelatedFor() executes the following code at line 70:

        $coll = $this->getTable()->getConnection()->query($dql, $id);
        $related = $coll[0];

        As you can see it accesses the first element by using index "0" in $coll and hence ignores a modified ATTR_COLL_KEY-setting, for instance:

        $this->setAttribute(Doctrine_Core::ATTR_COLL_KEY, 'id');

        Fortunately I had two models (ForeignA and ForeignB) in my project which both have an one-to-one relation to a third model (Main). That helped me finding this bug which causes the following strange behavior:

        // program 1:

        $m = new Main();
        $m->name = 'M1';
        $m->setForeignA(new ForeignA()); // has ATTR_COLL_KEY changed to 'id'
        $m->setForeignB(new ForeignB());
        $m->save();

        // program 2:

        $m = Doctrine_Core::getTable('M1')->findOneBy('name', 'M1');
        $m->getForeignA()->exists(); // false
        $m->getForeignB()->exists(); // true

        -------------------------

        The big problem about this issue is that behavior is inconsistent. If you don't split the example above into two separate programs/processes you won't have problems, since Doctrine accesses the reference which was stored when calling save().

        You will get into trouble using functional tests in Symfony. Since there is only a single process for all requests I wasn't able to reproduce a problem caused by this bug which appeared in the production environment.

        -------------------------

        Edit:

        Doctrine_Connection is affected as well.

        A solution is to replace
        Doctrine_Relation_ForeignKey::fetchRelatedFor() executes the following code at line 70:

        $coll = $this->getTable()->getConnection()->query($dql, $id);
        $related = $coll[0];

        As you can see it accesses the first element by using index "0" in $coll and hence ignores a modified ATTR_COLL_KEY-setting, for instance:

        $this->setAttribute(Doctrine_Core::ATTR_COLL_KEY, 'id');

        Fortunately I had two models (ForeignA and ForeignB) in my project which both have an one-to-one relation to a third model (Main). That helped me finding this bug which causes the following strange behavior:

        // program 1:

        $m = new Main();
        $m->name = 'M1';
        $m->setForeignA(new ForeignA()); // has ATTR_COLL_KEY changed to 'id'
        $m->setForeignB(new ForeignB());
        $m->save();

        // program 2:

        $m = Doctrine_Core::getTable('M1')->findOneBy('name', 'M1');
        $m->getForeignA()->exists(); // false
        $m->getForeignB()->exists(); // true

        -------------------------

        The big problem about this issue is that behavior is inconsistent. If you don't split the example above into two separate programs/processes you won't have problems, since Doctrine accesses the reference which was stored when calling save().

        You will get into trouble using functional tests in Symfony. Since there is only a single process for all requests I wasn't able to reproduce a problem caused by this bug which appeared in the production environment.

        -------------------------

        Edit:

        Doctrine_Connection::queryOne() is affected as well!

        A solution is to replace

        $coll = $this->getTable()->getConnection()->query($dql, $id);
        $related = $coll[0];

        by

        $related = $this->getTable()->getConnection()->query($dql, $id)->getFirst();
        Hide
        Uli Hecht added a comment -

        Suggested patch

        Show
        Uli Hecht added a comment - Suggested patch
        Uli Hecht made changes -
        Attachment ForeignKey.php.patch [ 11167 ]
        Guilherme Blanco made changes -
        Fix Version/s 1.2.4 [ 10063 ]
        Hide
        joao guermandi added a comment -

        Implementação

        Show
        joao guermandi added a comment - Implementação
        joao guermandi made changes -

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

          People

          • Assignee:
            Jonathan H. Wage
            Reporter:
            Uli Hecht
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated: