diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index b5eebcdde..5fa349933 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -29,6 +29,7 @@ use ReflectionClass; use Doctrine\Common\Persistence\Mapping\ClassMetadata; use Doctrine\Common\ClassLoader; use Doctrine\ORM\Cache\CacheException; +use Doctrine\ORM\Cache\AssociationCacheEntry; /** * A ClassMetadata instance holds all the object-relational mapping metadata @@ -718,7 +719,7 @@ class ClassMetadataInfo implements ClassMetadata $id = []; foreach ($this->identifier as $idField) { - $value = $this->reflFields[$idField]->getValue($entity); + $value = $this->getIndentifierValue($entity, $idField); if (null !== $value) { $id[$idField] = $value; @@ -729,7 +730,7 @@ class ClassMetadataInfo implements ClassMetadata } $id = $this->identifier[0]; - $value = $this->reflFields[$id]->getValue($entity); + $value = $this->getIndentifierValue($entity, $id); if (null === $value) { return []; @@ -738,6 +739,15 @@ class ClassMetadataInfo implements ClassMetadata return [$id => $value]; } + private function getIndentifierValue($entity, $id) + { + if ($entity instanceof AssociationCacheEntry) { + return $entity->identifier[$id]; + } + + return $this->reflFields[$id]->getValue($entity); + } + /** * Populates the entity identifier of an entity. * diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6217Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6217Test.php new file mode 100644 index 000000000..d87b9642e --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/GH6217Test.php @@ -0,0 +1,162 @@ +enableSecondLevelCache(); + + parent::setUp(); + + $this->_schemaTool->createSchema( + [ + $this->_em->getClassMetadata(GH6217User::class), + $this->_em->getClassMetadata(GH6217Profile::class), + $this->_em->getClassMetadata(GH6217Category::class), + $this->_em->getClassMetadata(GH6217UserProfile::class), + ] + ); + } + + /** + * @group 6217 + */ + public function testRetrievingCacheShouldNotThrowUndefinedIndexException() + { + $user = new GH6217User(1, 'user 1'); + $profile = new GH6217Profile(1); + $category = new GH6217Category(1, 'category 1'); + $userProfile = new GH6217UserProfile($user, $profile, $category); + + $this->_em->persist($category); + $this->_em->persist($user); + $this->_em->persist($profile); + $this->_em->persist($userProfile); + $this->_em->flush(); + $this->_em->clear(); + + $repository = $this->_em->getRepository(GH6217UserProfile::class); + $filters = ['user' => 1, 'category' => 1]; + + $this->assertCount(1, $repository->findBy($filters)); + $queryCount = $this->getCurrentQueryCount(); + + $this->_em->clear(); + + $this->assertCount(1, $repository->findBy($filters)); + $this->assertEquals($queryCount, $this->getCurrentQueryCount()); + } +} + +/** + * @Entity + * @Cache(usage="NONSTRICT_READ_WRITE") + */ +class GH6217User +{ + /** + * @Id + * @Column(type="integer") + * + * @var int + */ + public $id; + + /** + * @Column(type="string", length=60, unique=true) + * + * @var string + */ + public $username; + + public function __construct(int $id, string $username) + { + $this->id = $id; + $this->username = $username; + } +} + +/** + * @Entity + * @Cache(usage="NONSTRICT_READ_WRITE") + */ +class GH6217Profile +{ + /** + * @Id + * @Column(type="integer") + * + * @var int + */ + public $id; + + public function __construct(int $id) + { + $this->id = $id; + } +} + +/** + * @Entity + * @Cache(usage="NONSTRICT_READ_WRITE") + */ +class GH6217Category +{ + /** + * @Id + * @Column(type="integer") + * + * @var int + */ + public $id; + + public function __construct(int $id) + { + $this->id = $id; + } +} + +/** + * @Entity + * @Cache(usage="NONSTRICT_READ_WRITE") + */ +class GH6217UserProfile +{ + /** + * @Id + * @Cache("NONSTRICT_READ_WRITE") + * @ManyToOne(targetEntity="GH6217User") + * @JoinColumn(nullable=false) + * + * @var GH6217User + */ + public $user; + + /** + * @Id + * @Cache("NONSTRICT_READ_WRITE") + * @ManyToOne(targetEntity="GH6217Profile", fetch="EAGER") + * + * @var GH6217Profile + */ + public $profile; + + /** + * @Id + * @Cache("NONSTRICT_READ_WRITE") + * @ManyToOne(targetEntity="GH6217Category", fetch="EAGER") + * + * @var GH6217Category + */ + public $category; + + public function __construct(GH6217User $user, GH6217Profile $profile, GH6217Category $category) + { + $this->user = $user; + $this->profile = $profile; + $this->category = $category; + } +}