diff --git a/lib/Doctrine/ORM/Cache/DefaultQueryCache.php b/lib/Doctrine/ORM/Cache/DefaultQueryCache.php index 076fe3beb..3ac206547 100644 --- a/lib/Doctrine/ORM/Cache/DefaultQueryCache.php +++ b/lib/Doctrine/ORM/Cache/DefaultQueryCache.php @@ -122,11 +122,9 @@ class DefaultQueryCache implements QueryCache // @TODO - move to cache hydration component foreach ($entry->result as $index => $entry) { - $entityEntry = is_array($entries) && array_key_exists($index, $entries) ? $entries[$index] : null; if ($entityEntry === null) { - if ($this->cacheLogger !== null) { $this->cacheLogger->entityCacheMiss($regionName, $cacheKeys->identifiers[$index]); } @@ -139,7 +137,6 @@ class DefaultQueryCache implements QueryCache } if ( ! $hasRelation) { - $result[$index] = $this->uow->createEntity($entityEntry->class, $entityEntry->resolveAssociationEntries($this->em), self::$hints); continue; @@ -178,14 +175,20 @@ class DefaultQueryCache implements QueryCache continue; } - $collection = new PersistentCollection($this->em, $assocMetadata, new ArrayCollection()); + $generateKeys = function ($id) use ($assocMetadata): EntityCacheKey { + return new EntityCacheKey($assocMetadata->rootEntityName, $id); + }; + + $collection = new PersistentCollection($this->em, $assocMetadata, new ArrayCollection()); + $assocKeys = new CollectionCacheEntry(array_map($generateKeys, $assoc['list'])); + $assocEntries = $assocRegion->getMultiple($assocKeys); foreach ($assoc['list'] as $assocIndex => $assocId) { + $assocEntry = is_array($assocEntries) && array_key_exists($assocIndex, $assocEntries) ? $assocEntries[$assocIndex] : null; - if (($assocEntry = $assocRegion->get($assocKey = new EntityCacheKey($assocMetadata->rootEntityName, $assocId))) === null) { - + if ($assocEntry === null) { if ($this->cacheLogger !== null) { - $this->cacheLogger->entityCacheMiss($assocRegion->getName(), $assocKey); + $this->cacheLogger->entityCacheMiss($assocRegion->getName(), $assocKeys->identifiers[$assocIndex]); } $this->uow->hydrationComplete(); @@ -198,7 +201,7 @@ class DefaultQueryCache implements QueryCache $collection->hydrateSet($assocIndex, $element); if ($this->cacheLogger !== null) { - $this->cacheLogger->entityCacheHit($assocRegion->getName(), $assocKey); + $this->cacheLogger->entityCacheHit($assocRegion->getName(), $assocKeys->identifiers[$assocIndex]); } } diff --git a/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php b/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php index e011159bd..58eddd375 100644 --- a/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/DefaultQueryCacheTest.php @@ -125,8 +125,7 @@ class DefaultQueryCacheTest extends OrmTestCase $stateClass = $this->em->getClassMetadata(State::class); $rsm->addRootEntityFromClassMetadata(City::class, 'c'); - $rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name'] - ); + $rsm->addJoinedEntityFromClassMetadata(State::class, 's', 'c', 'state', ['id'=>'state_id', 'name'=>'state_name']); for ($i = 0; $i < 4; $i++) { $state = new State("State $i"); @@ -283,8 +282,47 @@ class DefaultQueryCacheTest extends OrmTestCase $key = new QueryCacheKey('query.key1', 0); $entry = new QueryCacheEntry( [ - ['identifier' => ['id' => 1]], - ['identifier' => ['id' => 2]] + ['identifier' => ['id' => 1]], + ['identifier' => ['id' => 2]] + ] + ); + + $data = [ + ['id'=>1, 'name' => 'Foo'], + ['id'=>2, 'name' => 'Bar'] + ]; + + $this->region->addReturn('get', $entry); + + $this->region->addReturn( + 'getMultiple', + [ + new EntityCacheEntry(Country::class, $data[0]), + new EntityCacheEntry(Country::class, $data[1]) + ] + ); + + $rsm->addRootEntityFromClassMetadata(Country::class, 'c'); + + $result = $this->queryCache->get($key, $rsm); + + $this->assertCount(2, $result); + $this->assertInstanceOf(Country::class, $result[0]); + $this->assertInstanceOf(Country::class, $result[1]); + $this->assertEquals(1, $result[0]->getId()); + $this->assertEquals(2, $result[1]->getId()); + $this->assertEquals('Foo', $result[0]->getName()); + $this->assertEquals('Bar', $result[1]->getName()); + } + + public function testGetWithAssociation() + { + $rsm = new ResultSetMappingBuilder($this->em); + $key = new QueryCacheKey('query.key1', 0); + $entry = new QueryCacheEntry( + [ + ['identifier' => ['id' => 1]], + ['identifier' => ['id' => 2]] ] );