Failed Conditions
Push — master ( 2ade86...13f838 )
by Jonathan
18s
created

Cache/Persister/Entity/AbstractEntityPersister.php (9 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the MIT license. For more information, see
18
 * <http://www.doctrine-project.org>.
19
 */
20
21
namespace Doctrine\ORM\Cache\Persister\Entity;
22
23
use Doctrine\ORM\Cache;
24
use Doctrine\ORM\Cache\Region;
25
use Doctrine\ORM\Cache\EntityCacheKey;
26
use Doctrine\ORM\Cache\CollectionCacheKey;
27
use Doctrine\ORM\Cache\TimestampCacheKey;
28
use Doctrine\ORM\Cache\QueryCacheKey;
29
use Doctrine\ORM\Cache\Persister\CachedPersister;
30
use Doctrine\ORM\Mapping\ClassMetadata;
31
use Doctrine\ORM\PersistentCollection;
32
use Doctrine\ORM\EntityManagerInterface;
33
use Doctrine\ORM\Persisters\Entity\EntityPersister;
34
35
use Doctrine\Common\Util\ClassUtils;
36
use Doctrine\Common\Collections\Criteria;
37
38
/**
39
 * @author Fabio B. Silva <[email protected]>
40
 * @since 2.5
41
 */
42
abstract class AbstractEntityPersister implements CachedEntityPersister
43
{
44
     /**
45
     * @var \Doctrine\ORM\UnitOfWork
46
     */
47
    protected $uow;
48
49
    /**
50
     * @var \Doctrine\ORM\Mapping\ClassMetadataFactory
51
     */
52
    protected $metadataFactory;
53
54
    /**
55
     * @var \Doctrine\ORM\Persisters\Entity\EntityPersister
56
     */
57
    protected $persister;
58
59
    /**
60
     * @var \Doctrine\ORM\Mapping\ClassMetadata
61
     */
62
    protected $class;
63
64
     /**
65
     * @var array
66
     */
67
    protected $queuedCache = [];
68
69
    /**
70
     * @var \Doctrine\ORM\Cache\Region
71
     */
72
    protected $region;
73
74
    /**
75
     * @var \Doctrine\ORM\Cache\TimestampRegion
76
     */
77
    protected $timestampRegion;
78
79
    /**
80
     * @var \Doctrine\ORM\Cache\TimestampCacheKey
81
     */
82
    protected $timestampKey;
83
84
    /**
85
     * @var \Doctrine\ORM\Cache\EntityHydrator
86
     */
87
    protected $hydrator;
88
89
    /**
90
     * @var \Doctrine\ORM\Cache
91
     */
92
    protected $cache;
93
94
    /**
95
     * @var \Doctrine\ORM\Cache\Logging\CacheLogger
96
     */
97
    protected $cacheLogger;
98
99
    /**
100
     * @var string
101
     */
102
    protected $regionName;
103
104
    /**
105
     * Associations configured as FETCH_EAGER, as well as all inverse one-to-one associations.
106
     *
107
     * @var array|null
108
     */
109
    protected $joinedAssociations;
110
111
    /**
112
     * @param \Doctrine\ORM\Persisters\Entity\EntityPersister $persister The entity persister to cache.
113
     * @param \Doctrine\ORM\Cache\Region                      $region    The entity cache region.
114
     * @param \Doctrine\ORM\EntityManagerInterface            $em        The entity manager.
115
     * @param \Doctrine\ORM\Mapping\ClassMetadata             $class     The entity metadata.
116
     */
117 208
    public function __construct(EntityPersister $persister, Region $region, EntityManagerInterface $em, ClassMetadata $class)
118
    {
119 208
        $configuration  = $em->getConfiguration();
120 208
        $cacheConfig    = $configuration->getSecondLevelCacheConfiguration();
121 208
        $cacheFactory   = $cacheConfig->getCacheFactory();
122
123 208
        $this->class            = $class;
124 208
        $this->region           = $region;
125 208
        $this->persister        = $persister;
126 208
        $this->cache            = $em->getCache();
127 208
        $this->regionName       = $region->getName();
128 208
        $this->uow              = $em->getUnitOfWork();
129 208
        $this->metadataFactory  = $em->getMetadataFactory();
130 208
        $this->cacheLogger      = $cacheConfig->getCacheLogger();
131 208
        $this->timestampRegion  = $cacheFactory->getTimestampRegion();
132 208
        $this->hydrator         = $cacheFactory->buildEntityHydrator($em, $class);
133 208
        $this->timestampKey     = new TimestampCacheKey($this->class->rootEntityName);
134 208
    }
135
136
    /**
137
     * {@inheritdoc}
138
     */
139 98
    public function addInsert($entity)
140
    {
141 98
        $this->persister->addInsert($entity);
142 98
    }
143
144
    /**
145
     * {@inheritdoc}
146
     */
147 3
    public function getInserts()
148
    {
149 3
        return $this->persister->getInserts();
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155 3
    public function getSelectSQL($criteria, $assoc = null, $lockMode = null, $limit = null, $offset = null, array $orderBy = null)
156
    {
157 3
        return $this->persister->getSelectSQL($criteria, $assoc, $lockMode, $limit, $offset, $orderBy);
158
    }
159
160
    /**
161
     * {@inheritDoc}
162
     */
163
    public function getCountSQL($criteria = [])
164
    {
165
        return $this->persister->getCountSQL($criteria);
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171 9
    public function getInsertSQL()
172
    {
173 9
        return $this->persister->getInsertSQL();
174
    }
175
176
    /**
177
     * {@inheritdoc}
178
     */
179 17
    public function getResultSetMapping()
180
    {
181 17
        return $this->persister->getResultSetMapping();
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187 3
    public function getSelectConditionStatementSQL($field, $value, $assoc = null, $comparison = null)
188
    {
189 3
        return $this->persister->getSelectConditionStatementSQL($field, $value, $assoc, $comparison);
190
    }
191
192
    /**
193
     * {@inheritdoc}
194
     */
195 4
    public function exists($entity, Criteria $extraConditions = null)
196
    {
197 4
        if (null === $extraConditions) {
198 4
            $key = new EntityCacheKey($this->class->rootEntityName, $this->class->getIdentifierValues($entity));
199
200 4
            if ($this->region->contains($key)) {
201 1
                return true;
202
            }
203
        }
204
205 4
        return $this->persister->exists($entity, $extraConditions);
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211 125
    public function getCacheRegion()
212
    {
213 125
        return $this->region;
214
    }
215
216
    /**
217
     * @return \Doctrine\ORM\Cache\EntityHydrator
218
     */
219 45
    public function getEntityHydrator()
220
    {
221 45
        return $this->hydrator;
222
    }
223
224
    /**
225
     * {@inheritdoc}
226
     */
227 38
    public function storeEntityCache($entity, EntityCacheKey $key)
228
    {
229 38
        $class      = $this->class;
230 38
        $className  = ClassUtils::getClass($entity);
231
232 38
        if ($className !== $this->class->name) {
233 3
            $class = $this->metadataFactory->getMetadataFor($className);
234
        }
235
236 38
        $entry  = $this->hydrator->buildCacheEntry($class, $key, $entity);
237 38
        $cached = $this->region->put($key, $entry);
238
239 38
        if ($this->cacheLogger && $cached) {
240 24
            $this->cacheLogger->entityCachePut($this->regionName, $key);
241
        }
242
243 38
        return $cached;
244
    }
245
246
    /**
247
     * @param object $entity
248
     */
249 29
    private function storeJoinedAssociations($entity)
250
    {
251 29
        if ($this->joinedAssociations === null) {
252 29
            $associations = [];
253
254 29
            foreach ($this->class->associationMappings as $name => $assoc) {
255 23
                if (isset($assoc['cache']) &&
256 23
                    ($assoc['type'] & ClassMetadata::TO_ONE) &&
257 23
                    ($assoc['fetch'] === ClassMetadata::FETCH_EAGER || ! $assoc['isOwningSide'])) {
258
259 23
                    $associations[] = $name;
260
                }
261
            }
262
263 29
            $this->joinedAssociations = $associations;
264
        }
265
266 29
        foreach ($this->joinedAssociations as $name) {
267 2
            $assoc       = $this->class->associationMappings[$name];
268 2
            $assocEntity = $this->class->getFieldValue($entity, $name);
269
270 2
            if ($assocEntity === null) {
271
                continue;
272
            }
273
274 2
            $assocId        = $this->uow->getEntityIdentifier($assocEntity);
275 2
            $assocMetadata  = $this->metadataFactory->getMetadataFor($assoc['targetEntity']);
276 2
            $assocKey       = new EntityCacheKey($assocMetadata->rootEntityName, $assocId);
277 2
            $assocPersister = $this->uow->getEntityPersister($assoc['targetEntity']);
278
279 2
            $assocPersister->storeEntityCache($assocEntity, $assocKey);
280
        }
281 29
    }
282
283
    /**
284
     * Generates a string of currently query
285
     *
286
     * @param array   $query
287
     * @param string  $criteria
288
     * @param array   $orderBy
289
     * @param integer $limit
290
     * @param integer $offset
291
     *
292
     * @return string
293
     */
294 17
    protected function getHash($query, $criteria, array $orderBy = null, $limit = null, $offset = null)
295
    {
296 17
        list($params) = ($criteria instanceof Criteria)
297 6
            ? $this->persister->expandCriteriaParameters($criteria)
298 17
            : $this->persister->expandParameters($criteria);
299
300 17
        return sha1($query . serialize($params) . serialize($orderBy) . $limit . $offset);
301
    }
302
303
    /**
304
     * {@inheritdoc}
305
     */
306 3
    public function expandParameters($criteria)
307
    {
308 3
        return $this->persister->expandParameters($criteria);
309
    }
310
311
    /**
312
     * {@inheritdoc}
313
     */
314 3
    public function expandCriteriaParameters(Criteria $criteria)
315
    {
316 3
        return $this->persister->expandCriteriaParameters($criteria);
317
    }
318
319
    /**
320
     * {@inheritdoc}
321
     */
322 14
    public function getClassMetadata()
323
    {
324 14
        return $this->persister->getClassMetadata();
325
    }
326
327
    /**
328
     * {@inheritdoc}
329
     */
330 3
    public function getManyToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
331
    {
332 3
        return $this->persister->getManyToManyCollection($assoc, $sourceEntity, $offset, $limit);
333
    }
334
335
    /**
336
     * {@inheritdoc}
337
     */
338 3
    public function getOneToManyCollection(array $assoc, $sourceEntity, $offset = null, $limit = null)
339
    {
340 3
        return $this->persister->getOneToManyCollection($assoc, $sourceEntity, $offset, $limit);
341
    }
342
343
    /**
344
     * {@inheritdoc}
345
     */
346 3
    public function getOwningTable($fieldName)
347
    {
348 3
        return $this->persister->getOwningTable($fieldName);
349
    }
350
351
    /**
352
     * {@inheritdoc}
353
     */
354 98
    public function executeInserts()
355
    {
356 98
        $this->queuedCache['insert'] = $this->persister->getInserts();
357
358 98
        return $this->persister->executeInserts();
359
    }
360
361
    /**
362
     * {@inheritdoc}
363
     */
364 6
    public function load(array $criteria, $entity = null, $assoc = null, array $hints = [], $lockMode = null, $limit = null, array $orderBy = null)
365
    {
366 6
        if ($entity !== null || $assoc !== null || ! empty($hints) || $lockMode !== null) {
367 3
            return $this->persister->load($criteria, $entity, $assoc, $hints, $lockMode, $limit, $orderBy);
368
        }
369
370
        //handle only EntityRepository#findOneBy
371 3
        $query      = $this->persister->getSelectSQL($criteria, null, null, $limit, null, $orderBy);
372 3
        $hash       = $this->getHash($query, $criteria, null, null, null);
373 3
        $rsm        = $this->getResultSetMapping();
374 3
        $queryKey   = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
375 3
        $queryCache = $this->cache->getQueryCache($this->regionName);
376 3
        $result     = $queryCache->get($queryKey, $rsm);
377
378 3 View Code Duplication
        if ($result !== null) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
379 3
            if ($this->cacheLogger) {
380 3
                $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
381
            }
382
383 3
            return $result[0];
384
        }
385
386 3
        if (($result = $this->persister->load($criteria, $entity, $assoc, $hints, $lockMode, $limit, $orderBy)) === null) {
387
            return null;
388
        }
389
390 3
        $cached = $queryCache->put($queryKey, $rsm, [$result]);
391
392 3 View Code Duplication
        if ($this->cacheLogger) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
393 3
            if ($result) {
394 3
                $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
395
            }
396
397 3
            if ($cached) {
398 3
                $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
399
            }
400
        }
401
402 3
        return $result;
403
    }
404
405
    /**
406
     * {@inheritdoc}
407
     */
408 8
    public function loadAll(array $criteria = [], array $orderBy = null, $limit = null, $offset = null)
409
    {
410 8
        $query      = $this->persister->getSelectSQL($criteria, null, null, $limit, $offset, $orderBy);
411 8
        $hash       = $this->getHash($query, $criteria, null, null, null);
412 8
        $rsm        = $this->getResultSetMapping();
413 8
        $queryKey   = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
414 8
        $queryCache = $this->cache->getQueryCache($this->regionName);
415 8
        $result     = $queryCache->get($queryKey, $rsm);
416
417 8 View Code Duplication
        if ($result !== null) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
418 5
            if ($this->cacheLogger) {
419 5
                $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
420
            }
421
422 5
            return $result;
423
        }
424
425 8
        $result = $this->persister->loadAll($criteria, $orderBy, $limit, $offset);
426 8
        $cached = $queryCache->put($queryKey, $rsm, $result);
427
428 8 View Code Duplication
        if ($this->cacheLogger) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
429 5
            if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
430 5
                $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
431
            }
432
433 5
            if ($cached) {
434 5
                $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
435
            }
436
        }
437
438 8
        return $result;
439
    }
440
441
    /**
442
     * {@inheritdoc}
443
     */
444 47
    public function loadById(array $identifier, $entity = null)
445
    {
446 47
        $cacheKey   = new EntityCacheKey($this->class->rootEntityName, $identifier);
447 47
        $cacheEntry = $this->region->get($cacheKey);
448 47
        $class      = $this->class;
449
450 47
        if ($cacheEntry !== null) {
451 39
            if ($cacheEntry->class !== $this->class->name) {
452 3
                $class = $this->metadataFactory->getMetadataFor($cacheEntry->class);
453
            }
454
455 39
            if (($entity = $this->hydrator->loadCacheEntry($class, $cacheKey, $cacheEntry, $entity)) !== null) {
456 39
                if ($this->cacheLogger) {
457 39
                    $this->cacheLogger->entityCacheHit($this->regionName, $cacheKey);
458
                }
459
460 39
                return $entity;
461
            }
462
        }
463
464 33
        $entity = $this->persister->loadById($identifier, $entity);
465
466 33
        if ($entity === null) {
467 2
            return null;
468
        }
469
470 33
        $class      = $this->class;
471 33
        $className  = ClassUtils::getClass($entity);
472
473 33
        if ($className !== $this->class->name) {
474 4
            $class = $this->metadataFactory->getMetadataFor($className);
475
        }
476
477 33
        $cacheEntry = $this->hydrator->buildCacheEntry($class, $cacheKey, $entity);
478 33
        $cached     = $this->region->put($cacheKey, $cacheEntry);
479
480 33
        if ($cached && (null === $this->joinedAssociations || $this->joinedAssociations)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->joinedAssociations of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
481 29
            $this->storeJoinedAssociations($entity);
482
        }
483
484 33
        if ($this->cacheLogger) {
485 30
            if ($cached) {
486 29
                $this->cacheLogger->entityCachePut($this->regionName, $cacheKey);
487
            }
488
489 30
            $this->cacheLogger->entityCacheMiss($this->regionName, $cacheKey);
490
        }
491
492 33
        return $entity;
493
    }
494
495
    /**
496
     * {@inheritDoc}
497
     */
498 2
    public function count($criteria = [])
499
    {
500 2
        return $this->persister->count($criteria);
501
    }
502
503
    /**
504
     * {@inheritdoc}
505
     */
506 6
    public function loadCriteria(Criteria $criteria)
507
    {
508 6
        $orderBy     = $criteria->getOrderings();
509 6
        $limit       = $criteria->getMaxResults();
510 6
        $offset      = $criteria->getFirstResult();
511 6
        $query       = $this->persister->getSelectSQL($criteria);
512 6
        $hash        = $this->getHash($query, $criteria, $orderBy, $limit, $offset);
513 6
        $rsm         = $this->getResultSetMapping();
514 6
        $queryKey    = new QueryCacheKey($hash, 0, Cache::MODE_NORMAL, $this->timestampKey);
515 6
        $queryCache  = $this->cache->getQueryCache($this->regionName);
516 6
        $cacheResult = $queryCache->get($queryKey, $rsm);
517
518 6 View Code Duplication
        if ($cacheResult !== null) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
519 3
            if ($this->cacheLogger) {
520 3
                $this->cacheLogger->queryCacheHit($this->regionName, $queryKey);
521
            }
522
523 3
            return $cacheResult;
524
        }
525
526 6
        $result = $this->persister->loadCriteria($criteria);
527 6
        $cached = $queryCache->put($queryKey, $rsm, $result);
528
529 6 View Code Duplication
        if ($this->cacheLogger) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
530 3
            if ($result) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
531 3
                $this->cacheLogger->queryCacheMiss($this->regionName, $queryKey);
532
            }
533
534 3
            if ($cached) {
535 3
                $this->cacheLogger->queryCachePut($this->regionName, $queryKey);
536
            }
537
        }
538
539 6
        return $result;
540
    }
541
542
    /**
543
     * {@inheritdoc}
544
     */
545 7 View Code Duplication
    public function loadManyToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
546
    {
547 7
        $persister = $this->uow->getCollectionPersister($assoc);
548 7
        $hasCache  = ($persister instanceof CachedPersister);
549 7
        $key       = null;
550
551 7
        if ( ! $hasCache) {
552 3
            return $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $coll);
553
        }
554
555 4
        $ownerId = $this->uow->getEntityIdentifier($coll->getOwner());
556 4
        $key     = $this->buildCollectionCacheKey($assoc, $ownerId);
557 4
        $list    = $persister->loadCollectionCache($coll, $key);
558
559 4
        if ($list !== null) {
560 4
            if ($this->cacheLogger) {
561 4
                $this->cacheLogger->collectionCacheHit($persister->getCacheRegion()->getName(), $key);
562
            }
563
564 4
            return $list;
565
        }
566
567 2
        $list = $this->persister->loadManyToManyCollection($assoc, $sourceEntity, $coll);
568
569 2
        $persister->storeCollectionCache($key, $list);
570
571 2
        if ($this->cacheLogger) {
572 2
            $this->cacheLogger->collectionCacheMiss($persister->getCacheRegion()->getName(), $key);
573
        }
574
575 2
        return $list;
576
    }
577
578
    /**
579
     * {@inheritdoc}
580
     */
581 17 View Code Duplication
    public function loadOneToManyCollection(array $assoc, $sourceEntity, PersistentCollection $coll)
582
    {
583 17
        $persister = $this->uow->getCollectionPersister($assoc);
584 17
        $hasCache  = ($persister instanceof CachedPersister);
585
586 17
        if ( ! $hasCache) {
587 3
            return $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $coll);
588
        }
589
590 14
        $ownerId = $this->uow->getEntityIdentifier($coll->getOwner());
591 14
        $key     = $this->buildCollectionCacheKey($assoc, $ownerId);
592 14
        $list    = $persister->loadCollectionCache($coll, $key);
593
594 14
        if ($list !== null) {
595 11
            if ($this->cacheLogger) {
596 11
                $this->cacheLogger->collectionCacheHit($persister->getCacheRegion()->getName(), $key);
597
            }
598
599 11
            return $list;
600
        }
601
602 13
        $list = $this->persister->loadOneToManyCollection($assoc, $sourceEntity, $coll);
603
604 13
        $persister->storeCollectionCache($key, $list);
605
606 13
        if ($this->cacheLogger) {
607 13
            $this->cacheLogger->collectionCacheMiss($persister->getCacheRegion()->getName(), $key);
608
        }
609
610 13
        return $list;
611
    }
612
613
    /**
614
     * {@inheritdoc}
615
     */
616 5
    public function loadOneToOneEntity(array $assoc, $sourceEntity, array $identifier = [])
617
    {
618 5
        return $this->persister->loadOneToOneEntity($assoc, $sourceEntity, $identifier);
619
    }
620
621
    /**
622
     * {@inheritdoc}
623
     */
624 3
    public function lock(array $criteria, $lockMode)
625
    {
626 3
        $this->persister->lock($criteria, $lockMode);
627 3
    }
628
629
    /**
630
     * {@inheritdoc}
631
     */
632 3
    public function refresh(array $id, $entity, $lockMode = null)
633
    {
634 3
        $this->persister->refresh($id, $entity, $lockMode);
635 3
    }
636
637
    /**
638
     * @param array $association
639
     * @param array $ownerId
640
     *
641
     * @return CollectionCacheKey
642
     */
643 18
    protected function buildCollectionCacheKey(array $association, $ownerId)
644
    {
645
        /** @var ClassMetadata $metadata */
646 18
        $metadata = $this->metadataFactory->getMetadataFor($association['sourceEntity']);
647
648 18
        return new CollectionCacheKey($metadata->rootEntityName, $association['fieldName'], $ownerId);
649
    }
650
}
651