Skip to content

Commit

Permalink
Fix single table inheritance with intermediate abstract class(es)
Browse files Browse the repository at this point in the history
Fixes #10625
  • Loading branch information
Heiko Przybyl committed Apr 20, 2023
1 parent a64f315 commit 1ae74b8
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 8 deletions.
16 changes: 8 additions & 8 deletions lib/Doctrine/ORM/Persisters/Entity/SingleTablePersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use Doctrine\ORM\Utility\PersisterHelper;

use function array_flip;
use function array_intersect;
use function array_map;
use function array_unshift;
use function implode;

/**
Expand Down Expand Up @@ -145,16 +148,13 @@ protected function getSelectConditionCriteriaSQL(Criteria $criteria)
/** @return string */
protected function getSelectConditionDiscriminatorValueSQL()
{
$values = [];
$values = array_map(
[$this->conn, 'quote'],
array_flip(array_intersect($this->class->discriminatorMap, $this->class->subClasses))
);

if ($this->class->discriminatorValue !== null) { // discriminators can be 0
$values[] = $this->conn->quote($this->class->discriminatorValue);
}

$discrValues = array_flip($this->class->discriminatorMap);

foreach ($this->class->subClasses as $subclassName) {
$values[] = $this->conn->quote($discrValues[$subclassName]);
array_unshift($values, $this->conn->quote($this->class->discriminatorValue));
}

$discColumnName = $this->class->getDiscriminatorColumn()['name'];
Expand Down
83 changes: 83 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/GH10625Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Tests\OrmFunctionalTestCase;

/**
* @group GH-10625
*/
class GH10625Test extends OrmFunctionalTestCase
{
protected function setUp(): void
{
parent::setUp();

$this->createSchemaForModels(
GH10625Root::class,
GH10625Middle::class,
GH10625Leaf::class
);
}

/**
* @dataProvider queryClasses
*/
public function testLoadFieldsFromAllClassesInHierarchy(string $queryClass): void
{
$entity = new GH10625Leaf();

$this->_em->persist($entity);
$this->_em->flush();
$this->_em->clear();

$loadedEntity = $this->_em->find($queryClass, $entity->id);

self::assertNotNull($loadedEntity);
self::assertInstanceOf(GH10625Leaf::class, $loadedEntity);
}

public static function queryClasses(): array
{
return [
'query via root entity' => [GH10625Root::class],
'query via intermediate entity' => [GH10625Middle::class],
'query via leaf entity' => [GH10625Leaf::class],
];
}
}

/**
* @ORM\Entity
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorMap({ "1": "GH10625Leaf"})
* ^- This DiscriminatorMap contains the single non-abstract Entity class only
*/
abstract class GH10625Root
{
/**
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
* @ORM\Column(type="integer")
*
* @var int
*/
public $id;
}

/**
* @ORM\Entity
*/
abstract class GH10625Middle extends GH10625Root
{
}

/**
* @ORM\Entity
*/
class GH10625Leaf extends GH10625Middle
{
}

0 comments on commit 1ae74b8

Please sign in to comment.