DDC-2575 Fixed issue with associations when parent is not yet loaded, but child is being created and no link happens.
This commit is contained in:
parent
df806977c6
commit
38b6838386
@ -404,6 +404,11 @@ class ObjectHydrator extends AbstractHydrator
|
||||
continue;
|
||||
}
|
||||
|
||||
$parentClass = $this->ce[$this->_rsm->aliasMap[$parentAlias]];
|
||||
$relationField = $this->_rsm->relationMap[$dqlAlias];
|
||||
$relation = $parentClass->associationMappings[$relationField];
|
||||
$reflField = $parentClass->reflFields[$relationField];
|
||||
|
||||
// Get a reference to the parent object to which the joined element belongs.
|
||||
if ($this->_rsm->isMixed && isset($this->rootAliases[$parentAlias])) {
|
||||
$first = reset($this->resultPointers);
|
||||
@ -411,20 +416,28 @@ class ObjectHydrator extends AbstractHydrator
|
||||
} else if (isset($this->resultPointers[$parentAlias])) {
|
||||
$parentObject = $this->resultPointers[$parentAlias];
|
||||
} else {
|
||||
// Parent object of relation not found, so skip it.
|
||||
// Parent object of relation not found, mark as not-fetched again
|
||||
$element = $this->getEntity($data, $dqlAlias);
|
||||
|
||||
// Update result pointer and provide initial fetch data for parent
|
||||
$this->resultPointers[$dqlAlias] = $element;
|
||||
$rowData[$parentAlias][$relationField] = $element;
|
||||
|
||||
// Mark as not-fetched again
|
||||
unset($this->_hints['fetched'][$parentAlias][$relationField]);
|
||||
|
||||
////unset($rowData[$dqlAlias]);
|
||||
//$rowData[$dqlAlias] = $data;
|
||||
continue;
|
||||
}
|
||||
|
||||
$parentClass = $this->ce[$this->_rsm->aliasMap[$parentAlias]];
|
||||
$oid = spl_object_hash($parentObject);
|
||||
$relationField = $this->_rsm->relationMap[$dqlAlias];
|
||||
$relation = $parentClass->associationMappings[$relationField];
|
||||
$reflField = $parentClass->reflFields[$relationField];
|
||||
$oid = spl_object_hash($parentObject);
|
||||
|
||||
// Check the type of the relation (many or single-valued)
|
||||
if ( ! ($relation['type'] & ClassMetadata::TO_ONE)) {
|
||||
$reflFieldValue = $reflField->getValue($parentObject);
|
||||
// PATH A: Collection-valued association
|
||||
$reflFieldValue = $reflField->getValue($parentObject);
|
||||
|
||||
if (isset($nonemptyComponents[$dqlAlias])) {
|
||||
$collKey = $oid . $relationField;
|
||||
if (isset($this->initializedCollections[$collKey])) {
|
||||
@ -473,6 +486,7 @@ class ObjectHydrator extends AbstractHydrator
|
||||
} else {
|
||||
// PATH B: Single-valued association
|
||||
$reflFieldValue = $reflField->getValue($parentObject);
|
||||
|
||||
if ( ! $reflFieldValue || isset($this->_hints[Query::HINT_REFRESH]) || ($reflFieldValue instanceof Proxy && !$reflFieldValue->__isInitialized__)) {
|
||||
// we only need to take action if this value is null,
|
||||
// we refresh the entity or its an unitialized proxy.
|
||||
@ -531,7 +545,7 @@ class ObjectHydrator extends AbstractHydrator
|
||||
|
||||
// check for existing result from the iterations before
|
||||
if ( ! isset($this->identifierMap[$dqlAlias][$id[$dqlAlias]])) {
|
||||
$element = $this->getEntity($rowData[$dqlAlias], $dqlAlias);
|
||||
$element = $this->getEntity($data, $dqlAlias);
|
||||
|
||||
if ($this->_rsm->isMixed) {
|
||||
$element = array($entityKey => $element);
|
||||
@ -566,10 +580,6 @@ class ObjectHydrator extends AbstractHydrator
|
||||
$index = $this->identifierMap[$dqlAlias][$id[$dqlAlias]];
|
||||
$this->resultPointers[$dqlAlias] = $result[$index];
|
||||
$resultKey = $index;
|
||||
/*if ($this->_rsm->isMixed) {
|
||||
$result[] = $result[$index];
|
||||
++$this->_resultCounter;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
160
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2575Test.php
Normal file
160
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2575Test.php
Normal file
@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
/**
|
||||
* @group DDC-2575
|
||||
*/
|
||||
class DDC2575Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
private $rootsEntities = array();
|
||||
private $aEntities = array();
|
||||
private $bEntities = array();
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2575Root'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2575A'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2575B'),
|
||||
));
|
||||
|
||||
$entityRoot1 = new DDC2575Root(1);
|
||||
$entityB1 = new DDC2575B(2);
|
||||
$entityA1 = new DDC2575A($entityRoot1, $entityB1);
|
||||
|
||||
$this->_em->persist($entityRoot1);
|
||||
$this->_em->persist($entityA1);
|
||||
$this->_em->persist($entityB1);
|
||||
|
||||
$entityRoot2 = new DDC2575Root(3);
|
||||
$entityB2 = new DDC2575B(4);
|
||||
$entityA2 = new DDC2575A($entityRoot2, $entityB2);
|
||||
|
||||
$this->_em->persist($entityRoot2);
|
||||
$this->_em->persist($entityA2);
|
||||
$this->_em->persist($entityB2);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$this->rootsEntities[] = $entityRoot1;
|
||||
$this->rootsEntities[] = $entityRoot2;
|
||||
|
||||
$this->aEntities[] = $entityA1;
|
||||
$this->aEntities[] = $entityA2;
|
||||
|
||||
$this->bEntities[] = $entityB1;
|
||||
$this->bEntities[] = $entityB2;
|
||||
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testHydrationIssue()
|
||||
{
|
||||
$repository = $this->_em->getRepository(__NAMESPACE__ . '\DDC2575Root');
|
||||
$qb = $repository->createQueryBuilder('r')
|
||||
->select('r, a, b')
|
||||
->leftJoin('r.aRelation', 'a')
|
||||
->leftJoin('a.bRelation', 'b');
|
||||
|
||||
$query = $qb->getQuery();
|
||||
$result = $query->getResult();
|
||||
|
||||
$this->assertCount(2, $result);
|
||||
|
||||
$row = $result[0];
|
||||
$this->assertNotNull($row->aRelation);
|
||||
$this->assertEquals(1, $row->id);
|
||||
$this->assertNotNull($row->aRelation->rootRelation);
|
||||
$this->assertSame($row, $row->aRelation->rootRelation);
|
||||
$this->assertNotNull($row->aRelation->bRelation);
|
||||
$this->assertEquals(2, $row->aRelation->bRelation->id);
|
||||
|
||||
$row = $result[1];
|
||||
$this->assertNotNull($row->aRelation);
|
||||
$this->assertEquals(3, $row->id);
|
||||
$this->assertNotNull($row->aRelation->rootRelation);
|
||||
$this->assertSame($row, $row->aRelation->rootRelation);
|
||||
$this->assertNotNull($row->aRelation->bRelation);
|
||||
$this->assertEquals(4, $row->aRelation->bRelation->id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2575Root
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $sampleField;
|
||||
|
||||
/**
|
||||
* @OneToOne(targetEntity="DDC2575A", mappedBy="rootRelation")
|
||||
**/
|
||||
public $aRelation;
|
||||
|
||||
public function __construct($id, $value = 0)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->sampleField = $value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2575A
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @OneToOne(targetEntity="DDC2575Root", inversedBy="aRelation")
|
||||
* @JoinColumn(name="root_id", referencedColumnName="id", nullable=FALSE, onDelete="CASCADE")
|
||||
*/
|
||||
public $rootRelation;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="DDC2575B")
|
||||
* @JoinColumn(name="b_id", referencedColumnName="id", nullable=FALSE, onDelete="CASCADE")
|
||||
*/
|
||||
public $bRelation;
|
||||
|
||||
public function __construct(DDC2575Root $rootRelation, DDC2575B $bRelation)
|
||||
{
|
||||
$this->rootRelation = $rootRelation;
|
||||
$this->bRelation = $bRelation;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class DDC2575B
|
||||
{
|
||||
/**
|
||||
* @Id
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @Column(type="integer")
|
||||
*/
|
||||
public $sampleField;
|
||||
|
||||
public function __construct($id, $value = 0)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->sampleField = $value;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user