1
0
mirror of synced 2025-03-11 15:16:10 +03:00

Merge pull request #6988 from kbond/inheritance-issue

Inheritance middle-layer doesn't get hydrated
This commit is contained in:
Marco Pivetta 2018-02-19 12:13:08 +01:00 committed by GitHub
commit a736a3713b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 142 additions and 6 deletions

View File

@ -24,6 +24,8 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Events;
use Doctrine\ORM\Mapping\ClassMetadata;
use PDO;
use function array_map;
use function in_array;
/**
* Base class for all hydrators. A hydrator is a class that provides some form
@ -296,11 +298,8 @@ abstract class AbstractHydrator
// If there are field name collisions in the child class, then we need
// to only hydrate if we are looking at the correct discriminator value
if(
isset($cacheKeyInfo['discriminatorColumn']) &&
isset($data[$cacheKeyInfo['discriminatorColumn']]) &&
// Note: loose comparison required. See https://github.com/doctrine/doctrine2/pull/6304#issuecomment-323294442
$data[$cacheKeyInfo['discriminatorColumn']] != $cacheKeyInfo['discriminatorValue']
if (isset($cacheKeyInfo['discriminatorColumn'], $data[$cacheKeyInfo['discriminatorColumn']])
&& ! in_array((string) $data[$cacheKeyInfo['discriminatorColumn']], $cacheKeyInfo['discriminatorValues'], true)
) {
break;
}
@ -401,7 +400,8 @@ abstract class AbstractHydrator
$columnInfo,
[
'discriminatorColumn' => $this->_rsm->discriminatorColumns[$ownerMap],
'discriminatorValue' => $classMetadata->discriminatorValue
'discriminatorValue' => $classMetadata->discriminatorValue,
'discriminatorValues' => $this->getDiscriminatorValues($classMetadata),
]
);
}
@ -454,6 +454,23 @@ abstract class AbstractHydrator
return null;
}
/**
* @return string[]
*/
private function getDiscriminatorValues(ClassMetadata $classMetadata) : array
{
$values = array_map(
function (string $subClass) : string {
return (string) $this->getClassMetadata($subClass)->discriminatorValue;
},
$classMetadata->subClasses
);
$values[] = (string) $classMetadata->discriminatorValue;
return $values;
}
/**
* Retrieve ClassMetadata associated to entity class name.
*

View File

@ -0,0 +1,119 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\AbstractQuery;
use Doctrine\Tests\OrmFunctionalTestCase;
/**
* @group 6937
*/
final class GH6937Test extends OrmFunctionalTestCase
{
/**
* {@inheritDoc}
*/
protected function setUp() : void
{
parent::setUp();
$this->setUpEntitySchema([GH6937Person::class, GH6937Employee::class, GH6937Manager::class]);
}
public function testPhoneNumberIsPopulatedWithFind() : void
{
$manager = new GH6937Manager();
$manager->name = 'Kevin';
$manager->phoneNumber = '555-5555';
$manager->department = 'Accounting';
$this->_em->persist($manager);
$this->_em->flush();
$this->_em->clear();
$persistedManager = $this->_em->find(GH6937Person::class, $manager->id);
self::assertSame('Kevin', $persistedManager->name);
self::assertSame('555-5555', $persistedManager->phoneNumber);
self::assertSame('Accounting', $persistedManager->department);
}
public function testPhoneNumberIsPopulatedWithQueryBuilderUsingSimpleObjectHydrator() : void
{
$manager = new GH6937Manager();
$manager->name = 'Kevin';
$manager->phoneNumber = '555-5555';
$manager->department = 'Accounting';
$this->_em->persist($manager);
$this->_em->flush();
$this->_em->clear();
$persistedManager = $this->_em->getRepository(GH6937Person::class)
->createQueryBuilder('e')
->where('e.id = :id')
->setParameter('id', $manager->id)
->getQuery()
->getOneOrNullResult(AbstractQuery::HYDRATE_SIMPLEOBJECT);
self::assertSame('Kevin', $persistedManager->name);
self::assertSame('555-5555', $persistedManager->phoneNumber);
self::assertSame('Accounting', $persistedManager->department);
}
public function testPhoneNumberIsPopulatedWithQueryBuilder() : void
{
$manager = new GH6937Manager();
$manager->name = 'Kevin';
$manager->phoneNumber = '555-5555';
$manager->department = 'Accounting';
$this->_em->persist($manager);
$this->_em->flush();
$this->_em->clear();
$persistedManager = $this->_em->getRepository(GH6937Person::class)
->createQueryBuilder('e')
->where('e.id = :id')
->setParameter('id', $manager->id)
->getQuery()
->getOneOrNullResult();
self::assertSame('Kevin', $persistedManager->name);
self::assertSame('555-5555', $persistedManager->phoneNumber);
self::assertSame('Accounting', $persistedManager->department);
}
}
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"employee"=GH6937Employee::class, "manager"=GH6937Manager::class})
*/
abstract class GH6937Person
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @Column(type="string") */
public $name;
}
/**
* @Entity
*/
abstract class GH6937Employee extends GH6937Person
{
/** @Column(type="string") */
public $phoneNumber;
}
/**
* @Entity
*/
class GH6937Manager extends GH6937Employee
{
/** @Column(type="string") */
public $department;
}