Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Critical
-
Resolution: Unresolved
-
Affects Version/s: 1.2.3
-
Fix Version/s: 1.2.4
-
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();
Activity
| 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 |
| 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(); |
| Attachment | ForeignKey.php.patch [ 11167 ] |
- 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[-21:-1].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)
Suggested patch