getConfiguration(); $cacheConfig = $configuration->getSecondLevelCacheConfiguration(); $cacheFactory = $cacheConfig->getCacheFactory(); $this->regionName = $region->getName(); $this->uow = $em->getUnitOfWork(); $this->metadataFactory = $em->getMetadataFactory(); $this->cacheLogger = $cacheConfig->getCacheLogger(); $this->hydrator = $cacheFactory->buildCollectionHydrator($em, $association); $this->sourceEntity = $em->getClassMetadata($association->sourceEntity); $this->targetEntity = $em->getClassMetadata($association->targetEntity); } public function getCacheRegion(): Region { return $this->region; } public function getSourceEntityMetadata(): ClassMetadata { return $this->sourceEntity; } public function getTargetEntityMetadata(): ClassMetadata { return $this->targetEntity; } public function loadCollectionCache(PersistentCollection $collection, CollectionCacheKey $key): array|null { $cache = $this->region->get($key); if ($cache === null) { return null; } return $this->hydrator->loadCacheEntry($this->sourceEntity, $key, $cache, $collection); } public function storeCollectionCache(CollectionCacheKey $key, Collection|array $elements): void { $associationMapping = $this->sourceEntity->associationMappings[$key->association]; $targetPersister = $this->uow->getEntityPersister($this->targetEntity->rootEntityName); assert($targetPersister instanceof CachedEntityPersister); $targetRegion = $targetPersister->getCacheRegion(); $targetHydrator = $targetPersister->getEntityHydrator(); // Only preserve ordering if association configured it if (! $associationMapping->isIndexed()) { // Elements may be an array or a Collection $elements = array_values($elements instanceof Collection ? $elements->getValues() : $elements); } $entry = $this->hydrator->buildCacheEntry($this->targetEntity, $key, $elements); foreach ($entry->identifiers as $index => $entityKey) { if ($targetRegion->contains($entityKey)) { continue; } $class = $this->targetEntity; $className = DefaultProxyClassNameResolver::getClass($elements[$index]); if ($className !== $this->targetEntity->name) { $class = $this->metadataFactory->getMetadataFor($className); } $entity = $elements[$index]; $entityEntry = $targetHydrator->buildCacheEntry($class, $entityKey, $entity); $targetRegion->put($entityKey, $entityEntry); } if ($this->region->put($key, $entry)) { $this->cacheLogger?->collectionCachePut($this->regionName, $key); } } public function contains(PersistentCollection $collection, object $element): bool { return $this->persister->contains($collection, $element); } public function containsKey(PersistentCollection $collection, mixed $key): bool { return $this->persister->containsKey($collection, $key); } public function count(PersistentCollection $collection): int { $ownerId = $this->uow->getEntityIdentifier($collection->getOwner()); $key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId); $entry = $this->region->get($key); if ($entry !== null) { return count($entry->identifiers); } return $this->persister->count($collection); } public function get(PersistentCollection $collection, mixed $index): mixed { return $this->persister->get($collection, $index); } /** * {@inheritDoc} */ public function slice(PersistentCollection $collection, int $offset, int|null $length = null): array { return $this->persister->slice($collection, $offset, $length); } /** * {@inheritDoc} */ public function loadCriteria(PersistentCollection $collection, Criteria $criteria): array { return $this->persister->loadCriteria($collection, $criteria); } }