diff --git a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php index b38a212c9..1fd327be8 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php @@ -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,9 @@ 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']]) && + if (isset($cacheKeyInfo['discriminatorColumn'], $data[$cacheKeyInfo['discriminatorColumn']]) // Note: loose comparison required. See https://github.com/doctrine/doctrine2/pull/6304#issuecomment-323294442 - $data[$cacheKeyInfo['discriminatorColumn']] != $cacheKeyInfo['discriminatorValue'] + && ! in_array($data[$cacheKeyInfo['discriminatorColumn']], $cacheKeyInfo['discriminatorValues']) ) { break; } @@ -397,11 +397,21 @@ abstract class AbstractHydrator // the current discriminator value must be saved in order to disambiguate fields hydration, // should there be field name collisions if ($classMetadata->parentClasses && isset($this->_rsm->discriminatorColumns[$ownerMap])) { + $discriminatorValues = array_map( + function (string $subClass) { + return $this->getClassMetadata($subClass)->discriminatorValue; + }, + $classMetadata->subClasses + ); + + $discriminatorValues[] = $classMetadata->discriminatorValue; + return $this->_cache[$key] = \array_merge( $columnInfo, [ 'discriminatorColumn' => $this->_rsm->discriminatorColumns[$ownerMap], - 'discriminatorValue' => $classMetadata->discriminatorValue + 'discriminatorValue' => $classMetadata->discriminatorValue, + 'discriminatorValues' => $discriminatorValues, ] ); }