Merge branch 'DDC-809'
This commit is contained in:
commit
6d20d7d5ed
@ -269,6 +269,9 @@ class ObjectHydrator extends AbstractHydrator
|
||||
// It's a joined result
|
||||
|
||||
$parentAlias = $this->_rsm->parentAliasMap[$dqlAlias];
|
||||
// we need the $path to save into the identifier map which entities were already
|
||||
// seen for this parent-child relationship
|
||||
$path = $parentAlias . '.' . $dqlAlias;
|
||||
|
||||
// Get a reference to the parent object to which the joined element belongs.
|
||||
if ($this->_rsm->isMixed && isset($this->_rootAliases[$parentAlias])) {
|
||||
@ -298,8 +301,8 @@ class ObjectHydrator extends AbstractHydrator
|
||||
$reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField);
|
||||
}
|
||||
|
||||
$indexExists = isset($this->_identifierMap[$dqlAlias][$id[$dqlAlias]]);
|
||||
$index = $indexExists ? $this->_identifierMap[$dqlAlias][$id[$dqlAlias]] : false;
|
||||
$indexExists = isset($this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]);
|
||||
$index = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false;
|
||||
$indexIsValid = $index !== false ? isset($reflFieldValue[$index]) : false;
|
||||
|
||||
if ( ! $indexExists || ! $indexIsValid) {
|
||||
@ -317,11 +320,11 @@ class ObjectHydrator extends AbstractHydrator
|
||||
$field = $this->_rsm->indexByMap[$dqlAlias];
|
||||
$indexValue = $this->_ce[$entityName]->reflFields[$field]->getValue($element);
|
||||
$reflFieldValue->hydrateSet($indexValue, $element);
|
||||
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $indexValue;
|
||||
$this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $indexValue;
|
||||
} else {
|
||||
$reflFieldValue->hydrateAdd($element);
|
||||
$reflFieldValue->last();
|
||||
$this->_identifierMap[$dqlAlias][$id[$dqlAlias]] = $reflFieldValue->key();
|
||||
$this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $reflFieldValue->key();
|
||||
}
|
||||
// Update result pointer
|
||||
$this->_resultPointers[$dqlAlias] = $element;
|
||||
|
111
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC809Test.php
Normal file
111
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC809Test.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\Models\CMS\CmsGroup;
|
||||
|
||||
require_once __DIR__ . '/../../../TestInit.php';
|
||||
|
||||
class DDC809Test extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->_schemaTool->createSchema(array(
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC809Variant'),
|
||||
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC809SpecificationValue')
|
||||
));
|
||||
|
||||
$conn = $this->_em->getConnection();
|
||||
$conn->insert('specification_value_test', array('specification_value_id' => 94589));
|
||||
$conn->insert('specification_value_test', array('specification_value_id' => 94593));
|
||||
$conn->insert('specification_value_test', array('specification_value_id' => 94606));
|
||||
$conn->insert('specification_value_test', array('specification_value_id' => 94607));
|
||||
$conn->insert('specification_value_test', array('specification_value_id' => 94609));
|
||||
$conn->insert('specification_value_test', array('specification_value_id' => 94711));
|
||||
|
||||
$conn->insert('variant_test', array('variant_id' => 545208));
|
||||
$conn->insert('variant_test', array('variant_id' => 545209));
|
||||
|
||||
$conn->insert('variant_specification_value_test', array('variant_id' => 545208, 'specification_value_id' => 94606));
|
||||
$conn->insert('variant_specification_value_test', array('variant_id' => 545208, 'specification_value_id' => 94607));
|
||||
$conn->insert('variant_specification_value_test', array('variant_id' => 545208, 'specification_value_id' => 94609));
|
||||
$conn->insert('variant_specification_value_test', array('variant_id' => 545208, 'specification_value_id' => 94711));
|
||||
|
||||
$conn->insert('variant_specification_value_test', array('variant_id' => 545209, 'specification_value_id' => 94589));
|
||||
$conn->insert('variant_specification_value_test', array('variant_id' => 545209, 'specification_value_id' => 94593));
|
||||
$conn->insert('variant_specification_value_test', array('variant_id' => 545209, 'specification_value_id' => 94606));
|
||||
$conn->insert('variant_specification_value_test', array('variant_id' => 545209, 'specification_value_id' => 94607));
|
||||
}
|
||||
|
||||
/**
|
||||
* @group DDC-809
|
||||
*/
|
||||
public function testIssue()
|
||||
{
|
||||
$result = $this->_em->createQueryBuilder()
|
||||
->select('Variant, SpecificationValue')
|
||||
->from('Doctrine\Tests\ORM\Functional\Ticket\DDC809Variant', 'Variant')
|
||||
->leftJoin('Variant.SpecificationValues', 'SpecificationValue')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
|
||||
$this->assertEquals(4, count($result[0]->getSpecificationValues()), "Works in test-setup.");
|
||||
$this->assertEquals(4, count($result[1]->getSpecificationValues()), "Only returns 2 in the case of the hydration bug.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="variant_test")
|
||||
* @Entity
|
||||
*/
|
||||
class DDC809Variant
|
||||
{
|
||||
/**
|
||||
* @Column(name="variant_id", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $variantId;
|
||||
|
||||
/**
|
||||
* @ManyToMany(targetEntity="DDC809SpecificationValue", inversedBy="Variants")
|
||||
* @JoinTable(name="variant_specification_value_test",
|
||||
* joinColumns={
|
||||
* @JoinColumn(name="variant_id", referencedColumnName="variant_id")
|
||||
* },
|
||||
* inverseJoinColumns={
|
||||
* @JoinColumn(name="specification_value_id", referencedColumnName="specification_value_id")
|
||||
* }
|
||||
* )
|
||||
*/
|
||||
protected $SpecificationValues;
|
||||
|
||||
public function getSpecificationValues()
|
||||
{
|
||||
return $this->SpecificationValues;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @Table(name="specification_value_test")
|
||||
* @Entity
|
||||
*/
|
||||
class DDC809SpecificationValue
|
||||
{
|
||||
/**
|
||||
* @Column(name="specification_value_id", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="AUTO")
|
||||
*/
|
||||
protected $specificationValueId;
|
||||
|
||||
/**
|
||||
* @var Variant
|
||||
*
|
||||
* @ManyToMany(targetEntity="DDC809Variant", mappedBy="SpecificationValues")
|
||||
*/
|
||||
protected $Variants;
|
||||
}
|
@ -888,4 +888,124 @@ class ObjectHydratorTest extends HydrationTestCase
|
||||
++$rowNum;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This issue tests if, with multiple joined multiple-valued collections the hydration is done correctly.
|
||||
*
|
||||
* User x Phonenumbers x Groups blow up the resultset quite a bit, however the hydration should correctly assemble those.
|
||||
*
|
||||
* @group DDC-809
|
||||
*/
|
||||
public function testManyToManyHydration()
|
||||
{
|
||||
$rsm = new ResultSetMapping;
|
||||
$rsm->addEntityResult('Doctrine\Tests\Models\CMS\CmsUser', 'u');
|
||||
$rsm->addFieldResult('u', 'u__id', 'id');
|
||||
$rsm->addFieldResult('u', 'u__name', 'name');
|
||||
$rsm->addJoinedEntityResult('Doctrine\Tests\Models\CMS\CmsGroup', 'g', 'u', 'groups');
|
||||
$rsm->addFieldResult('g', 'g__id', 'id');
|
||||
$rsm->addFieldResult('g', 'g__name', 'name');
|
||||
$rsm->addJoinedEntityResult('Doctrine\Tests\Models\CMS\CmsPhonenumber', 'p', 'u', 'phonenumbers');
|
||||
$rsm->addFieldResult('p', 'p__phonenumber', 'phonenumber');
|
||||
|
||||
// Faked result set
|
||||
$resultSet = array(
|
||||
array(
|
||||
'u__id' => '1',
|
||||
'u__name' => 'romanb',
|
||||
'g__id' => '3',
|
||||
'g__name' => 'TestGroupB',
|
||||
'p__phonenumber' => 1111,
|
||||
),
|
||||
array(
|
||||
'u__id' => '1',
|
||||
'u__name' => 'romanb',
|
||||
'g__id' => '5',
|
||||
'g__name' => 'TestGroupD',
|
||||
'p__phonenumber' => 1111,
|
||||
),
|
||||
array(
|
||||
'u__id' => '1',
|
||||
'u__name' => 'romanb',
|
||||
'g__id' => '3',
|
||||
'g__name' => 'TestGroupB',
|
||||
'p__phonenumber' => 2222,
|
||||
),
|
||||
array(
|
||||
'u__id' => '1',
|
||||
'u__name' => 'romanb',
|
||||
'g__id' => '5',
|
||||
'g__name' => 'TestGroupD',
|
||||
'p__phonenumber' => 2222,
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__name' => 'jwage',
|
||||
'g__id' => '2',
|
||||
'g__name' => 'TestGroupA',
|
||||
'p__phonenumber' => 3333,
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__name' => 'jwage',
|
||||
'g__id' => '3',
|
||||
'g__name' => 'TestGroupB',
|
||||
'p__phonenumber' => 3333,
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__name' => 'jwage',
|
||||
'g__id' => '4',
|
||||
'g__name' => 'TestGroupC',
|
||||
'p__phonenumber' => 3333,
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__name' => 'jwage',
|
||||
'g__id' => '5',
|
||||
'g__name' => 'TestGroupD',
|
||||
'p__phonenumber' => 3333,
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__name' => 'jwage',
|
||||
'g__id' => '2',
|
||||
'g__name' => 'TestGroupA',
|
||||
'p__phonenumber' => 4444,
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__name' => 'jwage',
|
||||
'g__id' => '3',
|
||||
'g__name' => 'TestGroupB',
|
||||
'p__phonenumber' => 4444,
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__name' => 'jwage',
|
||||
'g__id' => '4',
|
||||
'g__name' => 'TestGroupC',
|
||||
'p__phonenumber' => 4444,
|
||||
),
|
||||
array(
|
||||
'u__id' => '2',
|
||||
'u__name' => 'jwage',
|
||||
'g__id' => '5',
|
||||
'g__name' => 'TestGroupD',
|
||||
'p__phonenumber' => 4444,
|
||||
),
|
||||
);
|
||||
|
||||
$stmt = new HydratorMockStatement($resultSet);
|
||||
$hydrator = new \Doctrine\ORM\Internal\Hydration\ObjectHydrator($this->_em);
|
||||
|
||||
$result = $hydrator->hydrateAll($stmt, $rsm, array(Query::HINT_FORCE_PARTIAL_LOAD => true));
|
||||
|
||||
$this->assertEquals(2, count($result));
|
||||
$this->assertContainsOnly('Doctrine\Tests\Models\CMS\CmsUser', $result);
|
||||
$this->assertEquals(2, count($result[0]->groups));
|
||||
$this->assertEquals(2, count($result[0]->phonenumbers));
|
||||
$this->assertEquals(4, count($result[1]->groups));
|
||||
$this->assertEquals(2, count($result[1]->phonenumbers));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user