1
0
mirror of synced 2024-12-14 15:16:04 +03:00

Merge branch 'DDC-809'

This commit is contained in:
Benjamin Eberlei 2010-09-21 00:32:57 +02:00
commit 6d20d7d5ed
3 changed files with 238 additions and 4 deletions

View File

@ -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;

View 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;
}

View File

@ -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));
}
}