diff --git a/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php b/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php index 594ee747..baca0c65 100644 --- a/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php +++ b/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php @@ -12,6 +12,7 @@ use Symfony\Component\Cache\Adapter\DoctrineAdapter; use Symfony\Component\Cache\DoctrineProvider; +use function array_keys; use function array_reverse; use function array_unshift; use function explode; @@ -225,9 +226,18 @@ public function getMetadataFor($className) $this->wakeupReflection($cached, $this->getReflectionService()); } else { - foreach ($this->loadMetadata($realClassName) as $loadedClassName) { - $item = $this->cache->getItem($this->getCacheKey($loadedClassName)); - $item->set($this->loadedMetadata[$loadedClassName]); + $loadedMetadata = $this->loadMetadata($realClassName); + $classNames = array_combine( + array_map([$this, 'getCacheKey'], $loadedMetadata), + $loadedMetadata + ); + + foreach ($this->cache->getItems(array_keys($classNames)) as $item) { + if (!isset($classNames[$item->getKey()])) { + continue; + } + + $item->set($this->loadedMetadata[$classNames[$item->getKey()]]); $this->cache->saveDeferred($item); } @@ -450,6 +460,11 @@ protected function getCacheKey(string $realClassName): string return str_replace('\\', '__', $realClassName) . $this->cacheSalt; } + protected function getClassNameFromCacheKey(string $cacheKey): string + { + return str_replace('__', '\\', substr($cacheKey, -strlen($this->cacheSalt))); + } + /** * Gets the real class name of a class name that could be a proxy. */ diff --git a/tests/Doctrine/Tests/Persistence/Mapping/ClassMetadataFactoryTest.php b/tests/Doctrine/Tests/Persistence/Mapping/ClassMetadataFactoryTest.php index a7ce178b..b82ca2d7 100644 --- a/tests/Doctrine/Tests/Persistence/Mapping/ClassMetadataFactoryTest.php +++ b/tests/Doctrine/Tests/Persistence/Mapping/ClassMetadataFactoryTest.php @@ -176,6 +176,10 @@ public function testWillIgnoreCacheEntriesThatAreNotMetadataInstances(): void $item = $this->createMock(CacheItemInterface::class); assert($item instanceof CacheItemInterface || $item instanceof MockObject); + $item + ->expects(self::any()) + ->method('getKey') + ->willReturn($key); $item ->expects(self::any()) ->method('get') @@ -192,6 +196,11 @@ public function testWillIgnoreCacheEntriesThatAreNotMetadataInstances(): void ->method('getItem') ->with($key) ->willReturn($item); + $cacheDriver + ->expects(self::once()) + ->method('getItems') + ->with([$key]) + ->willReturn([$item]); $cacheDriver ->expects(self::once()) ->method('saveDeferred')