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();
        Uli Hecht made changes -
        Attachment ForeignKey.php.patch [ 11167 ]
        Guilherme Blanco made changes -
        Fix Version/s 1.2.4 [ 10063 ]
        joao guermandi made changes -

          People

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

            Dates

            • Created:
              Updated: