Completed
Pull Request — master (#1667)
by Julien
08:32
created

PersistentCollectionTrait::last()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
crap 1
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\ODM\MongoDB\PersistentCollection;
21
22
use Doctrine\Common\Collections\Collection as BaseCollection;
23
use Doctrine\ODM\MongoDB\DocumentManager;
24
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
25
use Doctrine\ODM\MongoDB\MongoDBException;
26
use Doctrine\ODM\MongoDB\UnitOfWork;
27
use Doctrine\ODM\MongoDB\Utility\CollectionHelper;
28
29
/**
30
 * Trait with methods needed to implement PersistentCollectionInterface.
31
 *
32
 * @since 1.1
33
 */
34
trait PersistentCollectionTrait
35
{
36
    /**
37
     * A snapshot of the collection at the moment it was fetched from the database.
38
     * This is used to create a diff of the collection at commit time.
39
     *
40
     * @var array
41
     */
42
    private $snapshot = array();
43
44
    /**
45
     * Collection's owning entity
46
     *
47
     * @var object
48
     */
49
    private $owner;
50
51
    /**
52
     * @var array
53
     */
54
    private $mapping;
55
56
    /**
57
     * Whether the collection is dirty and needs to be synchronized with the database
58
     * when the UnitOfWork that manages its persistent state commits.
59
     *
60
     * @var boolean
61
     */
62
    private $isDirty = false;
63
64
    /**
65
     * Whether the collection has already been initialized.
66
     *
67
     * @var boolean
68
     */
69
    private $initialized = true;
70
71
    /**
72
     * The wrapped Collection instance.
73
     *
74
     * @var BaseCollection
75
     */
76
    private $coll;
77
78
    /**
79
     * The DocumentManager that manages the persistence of the collection.
80
     *
81
     * @var DocumentManager
82
     */
83
    private $dm;
84
85
    /**
86
     * The UnitOfWork that manages the persistence of the collection.
87
     *
88
     * @var UnitOfWork
89
     */
90
    private $uow;
91
92
    /**
93
     * The raw mongo data that will be used to initialize this collection.
94
     *
95
     * @var array
96
     */
97
    private $mongoData = array();
98
99
    /**
100
     * Any hints to account for during reconstitution/lookup of the documents.
101
     *
102
     * @var array
103
     */
104
    private $hints = array();
105
106
    /** {@inheritdoc} */
107 2
    public function setDocumentManager(DocumentManager $dm)
108
    {
109 2
        $this->dm = $dm;
110 2
        $this->uow = $dm->getUnitOfWork();
111 2
    }
112
113
    /** {@inheritdoc} */
114 182
    public function setMongoData(array $mongoData)
115
    {
116 182
        $this->mongoData = $mongoData;
117 182
    }
118
119
    /** {@inheritdoc} */
120 158
    public function getMongoData()
121
    {
122 158
        return $this->mongoData;
123
    }
124
125
    /** {@inheritdoc} */
126 272
    public function setHints(array $hints)
127
    {
128 272
        $this->hints = $hints;
129 272
    }
130
131
    /** {@inheritdoc} */
132 176
    public function getHints()
133
    {
134 176
        return $this->hints;
135
    }
136
137
    /** {@inheritdoc} */
138 416
    public function initialize()
139
    {
140 416
        if ($this->initialized || ! $this->mapping) {
141 409
            return;
142
        }
143
144 173
        $newObjects = array();
145
146 173
        if ($this->isDirty) {
147
            // Remember any NEW objects added through add()
148 22
            $newObjects = $this->coll->toArray();
149
        }
150
151 173
        $this->initialized = true;
152
153 173
        $this->coll->clear();
154 173
        $this->uow->loadCollection($this);
155 172
        $this->takeSnapshot();
156
157 172
        $this->mongoData = array();
158
159
        // Reattach any NEW objects added through add()
160 172
        if ($newObjects) {
161 22
            foreach ($newObjects as $key => $obj) {
162 22
                if (CollectionHelper::isHash($this->mapping['strategy'])) {
163
                    $this->coll->set($key, $obj);
164
                } else {
165 22
                    $this->coll->add($obj);
166
                }
167
            }
168
169 22
            $this->isDirty = true;
170
        }
171 172
    }
172
173
    /**
174
     * Marks this collection as changed/dirty.
175
     */
176 203
    private function changed()
177
    {
178 203
        if ($this->isDirty) {
179 129
            return;
180
        }
181
182 203
        $this->isDirty = true;
183
184 203
        if ($this->needsSchedulingForDirtyCheck()) {
185 2
            $this->uow->scheduleForDirtyCheck($this->owner);
186
        }
187 203
    }
188
189
    /** {@inheritdoc} */
190 430
    public function isDirty()
191
    {
192 430
        if ($this->isDirty) {
193 283
            return true;
194
        }
195 378
        if (! $this->initialized && count($this->coll)) {
196
            // not initialized collection with added elements
197
            return true;
198
        }
199 378
        if ($this->initialized) {
200
            // if initialized let's check with last known snapshot
201 372
            return $this->coll->toArray() !== $this->snapshot;
202
        }
203 96
        return false;
204
    }
205
206
    /** {@inheritdoc} */
207 419
    public function setDirty($dirty)
208
    {
209 419
        $this->isDirty = $dirty;
210 419
    }
211
212
    /** {@inheritdoc} */
213 440
    public function setOwner($document, array $mapping)
214
    {
215 440
        $this->owner = $document;
216 440
        $this->mapping = $mapping;
217 440
    }
218
219
    /** {@inheritdoc} */
220 304
    public function takeSnapshot()
221
    {
222 304
        if (CollectionHelper::isList($this->mapping['strategy'])) {
223 290
            $array = $this->coll->toArray();
224 290
            $this->coll->clear();
225 290
            foreach ($array as $document) {
226 265
                $this->coll->add($document);
227
            }
228
        }
229 304
        $this->snapshot = $this->coll->toArray();
230 304
        $this->isDirty = false;
231 304
    }
232
233
    /** {@inheritdoc} */
234 23
    public function clearSnapshot()
235
    {
236 23
        $this->snapshot = array();
237 23
        $this->isDirty = $this->coll->count() ? true : false;
238 23
    }
239
240
    /** {@inheritdoc} */
241
    public function getSnapshot()
242
    {
243
        return $this->snapshot;
244
    }
245
246
    /** {@inheritdoc} */
247 90 View Code Duplication
    public function getDeleteDiff()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
248
    {
249 90
        return array_udiff_assoc(
250 90
            $this->snapshot,
251 90
            $this->coll->toArray(),
252
            function ($a, $b) { return $a === $b ? 0 : 1; }
253
        );
254
    }
255
256
    /** {@inheritdoc} */
257 View Code Duplication
    public function getDeletedDocuments()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
258
    {
259 153
        $compare = function ($a, $b) {
260 105
            $compareA = is_object($a) ? spl_object_hash($a) : $a;
261 105
            $compareb = is_object($b) ? spl_object_hash($b) : $b;
262 105
            return $compareA === $compareb ? 0 : ($compareA > $compareb ? 1 : -1);
263 153
        };
264 153
        return array_values(array_udiff(
265 153
            $this->snapshot,
266 153
            $this->coll->toArray(),
267 153
            $compare
268
        ));
269
    }
270
271
    /** {@inheritdoc} */
272 90 View Code Duplication
    public function getInsertDiff()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
273
    {
274 90
        return array_udiff_assoc(
275 90
            $this->coll->toArray(),
276 90
            $this->snapshot,
277
            function ($a, $b) { return $a === $b ? 0 : 1; }
278
        );
279
    }
280
281
    /** {@inheritdoc} */
282 View Code Duplication
    public function getInsertedDocuments()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
283
    {
284 4
        $compare = function ($a, $b) {
285 4
            $compareA = is_object($a) ? spl_object_hash($a) : $a;
286 4
            $compareb = is_object($b) ? spl_object_hash($b) : $b;
287 4
            return $compareA === $compareb ? 0 : ($compareA > $compareb ? 1 : -1);
288 4
        };
289 4
        return array_values(array_udiff(
290 4
            $this->coll->toArray(),
291 4
            $this->snapshot,
292 4
            $compare
293
        ));
294
    }
295
296
    /** {@inheritdoc} */
297 429
    public function getOwner()
298
    {
299 429
        return $this->owner;
300
    }
301
302
    /** {@inheritdoc} */
303 299
    public function getMapping()
304
    {
305 299
        return $this->mapping;
306
    }
307
308
    /** {@inheritdoc} */
309 5
    public function getTypeClass()
310
    {
311 5
        switch (true) {
312 5
            case ($this->dm === null):
313 1
                throw new MongoDBException('No DocumentManager is associated with this PersistentCollection, please set one using setDocumentManager method.');
314 4
            case (empty($this->mapping)):
315 1
                throw new MongoDBException('No mapping is associated with this PersistentCollection, please set one using setOwner method.');
316 3
            case (empty($this->mapping['targetDocument'])):
317 1
                throw new MongoDBException('Specifying targetDocument is required for the ClassMetadata to be obtained.');
318
            default:
319 2
                return $this->dm->getClassMetadata($this->mapping['targetDocument']);
320
        }
321
    }
322
323
    /** {@inheritdoc} */
324 275
    public function setInitialized($bool)
325
    {
326 275
        $this->initialized = $bool;
327 275
    }
328
329
    /** {@inheritdoc} */
330 18
    public function isInitialized()
331
    {
332 18
        return $this->initialized;
333
    }
334
335
    /** {@inheritdoc} */
336 17
    public function first()
337
    {
338 17
        $this->initialize();
339 16
        return $this->coll->first();
340
    }
341
342
    /** {@inheritdoc} */
343 2
    public function last()
344
    {
345 2
        $this->initialize();
346 2
        return $this->coll->last();
347
    }
348
349
    /**
350
     * {@inheritdoc}
351
     */
352 4
    public function remove($key)
353
    {
354 4
        return $this->doRemove($key, false);
355
    }
356
357
    /**
358
     * {@inheritdoc}
359
     */
360 17
    public function removeElement($element)
361
    {
362 17
        $this->initialize();
363 17
        $removed = $this->coll->removeElement($element);
364
365 17
        if ( ! $removed) {
366
            return $removed;
367
        }
368
369 17
        $this->changed();
370
371 17
        return $removed;
372
    }
373
374
    /**
375
     * {@inheritdoc}
376
     */
377
    public function containsKey($key)
378
    {
379
        $this->initialize();
380
        return $this->coll->containsKey($key);
381
    }
382
383
    /**
384
     * {@inheritdoc}
385
     */
386 2
    public function contains($element)
387
    {
388 2
        $this->initialize();
389 2
        return $this->coll->contains($element);
390
    }
391
392
    /**
393
     * {@inheritdoc}
394
     */
395
    public function exists(\Closure $p)
396
    {
397
        $this->initialize();
398
        return $this->coll->exists($p);
399
    }
400
401
    /**
402
     * {@inheritdoc}
403
     */
404 2
    public function indexOf($element)
405
    {
406 2
        $this->initialize();
407 2
        return $this->coll->indexOf($element);
408
    }
409
410
    /**
411
     * {@inheritdoc}
412
     */
413 19
    public function get($key)
414
    {
415 19
        $this->initialize();
416 19
        return $this->coll->get($key);
417
    }
418
419
    /**
420
     * {@inheritdoc}
421
     */
422
    public function getKeys()
423
    {
424
        $this->initialize();
425
        return $this->coll->getKeys();
426
    }
427
428
    /**
429
     * {@inheritdoc}
430
     */
431
    public function getValues()
432
    {
433
        $this->initialize();
434
        return $this->coll->getValues();
435
    }
436
437
    /**
438
     * {@inheritdoc}
439
     */
440 119
    public function count()
441
    {
442 119
        $count = $this->coll->count();
443
444
        // If this collection is inversed and not initialized, add the count returned from the database
445 119
        if ($this->mapping['isInverseSide'] && ! $this->initialized) {
446 11
            $documentPersister = $this->uow->getDocumentPersister(get_class($this->owner));
447 11
            $count += empty($this->mapping['repositoryMethod'])
448 10
                ? $documentPersister->createReferenceManyInverseSideQuery($this)->count(true)
449 2
                : $documentPersister->createReferenceManyWithRepositoryMethodCursor($this)->count(true);
450
        }
451
452 119
        return $count + ($this->initialized ? 0 : count($this->mongoData));
453
    }
454
455
    /**
456
     * {@inheritdoc}
457
     */
458 35
    public function set($key, $value)
459
    {
460 35
        return $this->doSet($key, $value, false);
461
    }
462
463
    /**
464
     * {@inheritdoc}
465
     */
466 158
    public function add($value)
467
    {
468 158
        return $this->doAdd($value, false);
469
    }
470
471
    /**
472
     * {@inheritdoc}
473
     */
474 405
    public function isEmpty()
475
    {
476 405
        return $this->initialized ? $this->coll->isEmpty() : $this->count() === 0;
477
    }
478
479
    /**
480
     * {@inheritdoc}
481
     */
482 352
    public function getIterator()
483
    {
484 352
        $this->initialize();
485 352
        return $this->coll->getIterator();
486
    }
487
488
    /**
489
     * {@inheritdoc}
490
     */
491 241
    public function map(\Closure $func)
492
    {
493 241
        $this->initialize();
494 241
        return $this->coll->map($func);
495
    }
496
497
    /**
498
     * {@inheritdoc}
499
     */
500
    public function filter(\Closure $p)
501
    {
502
        $this->initialize();
503
        return $this->coll->filter($p);
504
    }
505
506
    /**
507
     * {@inheritdoc}
508
     */
509
    public function forAll(\Closure $p)
510
    {
511
        $this->initialize();
512
        return $this->coll->forAll($p);
513
    }
514
515
    /**
516
     * {@inheritdoc}
517
     */
518
    public function partition(\Closure $p)
519
    {
520
        $this->initialize();
521
        return $this->coll->partition($p);
522
    }
523
524
    /**
525
     * {@inheritdoc}
526
     */
527 23
    public function toArray()
528
    {
529 23
        $this->initialize();
530 23
        return $this->coll->toArray();
531
    }
532
533
    /**
534
     * {@inheritdoc}
535
     */
536 29
    public function clear()
537
    {
538 29
        if ($this->initialized && $this->isEmpty()) {
539
            return;
540
        }
541
542 29
        if ($this->isOrphanRemovalEnabled()) {
543 28
            $this->initialize();
544 28
            foreach ($this->coll as $element) {
545 28
                $this->uow->scheduleOrphanRemoval($element);
546
            }
547
        }
548
549 29
        $this->mongoData = array();
550 29
        $this->coll->clear();
551
552
        // Nothing to do for inverse-side collections
553 29
        if ( ! $this->mapping['isOwningSide']) {
554
            return;
555
        }
556
557
        // Nothing to do if the collection was initialized but contained no data
558 29
        if ($this->initialized && empty($this->snapshot)) {
559 2
            return;
560
        }
561
562 27
        $this->changed();
563 27
        $this->uow->scheduleCollectionDeletion($this);
564 27
        $this->takeSnapshot();
565 27
    }
566
567
    /**
568
     * {@inheritdoc}
569
     */
570 1
    public function slice($offset, $length = null)
571
    {
572 1
        $this->initialize();
573 1
        return $this->coll->slice($offset, $length);
574
    }
575
576
    /**
577
     * Called by PHP when this collection is serialized. Ensures that only the
578
     * elements are properly serialized.
579
     *
580
     * @internal Tried to implement Serializable first but that did not work well
581
     *           with circular references. This solution seems simpler and works well.
582
     */
583 4
    public function __sleep()
584
    {
585 4
        return array('coll', 'initialized');
586
    }
587
588
    /* ArrayAccess implementation */
589
590
    /**
591
     * @see containsKey()
592
     */
593 2
    public function offsetExists($offset)
594
    {
595 2
        $this->initialize();
596 2
        return $this->coll->offsetExists($offset);
597
    }
598
599
    /**
600
     * @see get()
601
     */
602 82
    public function offsetGet($offset)
603
    {
604 82
        $this->initialize();
605 82
        return $this->coll->offsetGet($offset);
606
    }
607
608
    /**
609
     * @see add()
610
     * @see set()
611
     */
612 42
    public function offsetSet($offset, $value)
613
    {
614 42
        if ( ! isset($offset)) {
615 41
            return $this->doAdd($value, true);
616
        }
617
618 3
        return $this->doSet($offset, $value, true);
619
    }
620
621
    /**
622
     * @see remove()
623
     */
624 19
    public function offsetUnset($offset)
625
    {
626 19
        return $this->doRemove($offset, true);
627
    }
628
629
    public function key()
630
    {
631
        return $this->coll->key();
632
    }
633
634
    /**
635
     * Gets the element of the collection at the current iterator position.
636
     */
637 1
    public function current()
638
    {
639 1
        return $this->coll->current();
640
    }
641
642
    /**
643
     * Moves the internal iterator position to the next element.
644
     */
645
    public function next()
646
    {
647
        return $this->coll->next();
648
    }
649
650
    /**
651
     * {@inheritdoc}
652
     */
653 429
    public function unwrap()
654
    {
655 429
        return $this->coll;
656
    }
657
658
    /**
659
     * Cleanup internal state of cloned persistent collection.
660
     *
661
     * The following problems have to be prevented:
662
     * 1. Added documents are added to old PersistentCollection
663
     * 2. New collection is not dirty, if reused on other document nothing
664
     * changes.
665
     * 3. Snapshot leads to invalid diffs being generated.
666
     * 4. Lazy loading grabs entities from old owner object.
667
     * 5. New collection is connected to old owner and leads to duplicate keys.
668
     */
669 8
    public function __clone()
670
    {
671 8
        if (is_object($this->coll)) {
672 8
            $this->coll = clone $this->coll;
673
        }
674
675 8
        $this->initialize();
676
677 8
        $this->owner = null;
678 8
        $this->snapshot = array();
679
680 8
        $this->changed();
681 8
    }
682
683
    /**
684
     * Actual logic for adding an element to the collection.
685
     *
686
     * @param mixed $value
687
     * @param bool $arrayAccess
688
     * @return bool
689
     */
690 175
    private function doAdd($value, $arrayAccess)
691
    {
692
        /* Initialize the collection before calling add() so this append operation
693
         * uses the appropriate key. Otherwise, we risk overwriting original data
694
         * when $newObjects are re-added in a later call to initialize().
695
         */
696 175
        if (isset($this->mapping['strategy']) && CollectionHelper::isHash($this->mapping['strategy'])) {
697 12
            $this->initialize();
698
        }
699 175
        $arrayAccess ? $this->coll->offsetSet(null, $value) : $this->coll->add($value);
700 175
        $this->changed();
701
702 175 View Code Duplication
        if ($this->uow !== null && $this->isOrphanRemovalEnabled() && $value !== null) {
0 ignored issues
show
Duplication introduced by
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...
703 99
            $this->uow->unscheduleOrphanRemoval($value);
704
        }
705
706 175
        return true;
707
    }
708
709
    /**
710
     * Actual logic for removing element by its key.
711
     *
712
     * @param mixed $offset
713
     * @param bool $arrayAccess
714
     * @return mixed|void
715
     */
716 23
    private function doRemove($offset, $arrayAccess)
717
    {
718 23
        $this->initialize();
719 23
        $removed = $arrayAccess ? $this->coll->offsetUnset($offset) : $this->coll->remove($offset);
720
721 23
        if ( ! $removed && ! $arrayAccess) {
722
            return $removed;
723
        }
724
725 23
        $this->changed();
726
727 23
        return $removed;
728
    }
729
730
    /**
731
     * Actual logic for setting an element in the collection.
732
     *
733
     * @param mixed $offset
734
     * @param mixed $value
735
     * @param bool $arrayAccess
736
     * @return bool
737
     */
738 36
    private function doSet($offset, $value, $arrayAccess)
739
    {
740 36
        $arrayAccess ? $this->coll->offsetSet($offset, $value) : $this->coll->set($offset, $value);
741
742
        // Handle orphanRemoval
743 36 View Code Duplication
        if ($this->uow !== null && $this->isOrphanRemovalEnabled() && $value !== null) {
0 ignored issues
show
Duplication introduced by
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...
744 34
            $this->uow->unscheduleOrphanRemoval($value);
745
        }
746
747 36
        $this->changed();
748 36
    }
749
750
    /**
751
     * Returns whether or not this collection has orphan removal enabled.
752
     *
753
     * Embedded documents are automatically considered as "orphan removal enabled" because they might have references
754
     * that require to trigger cascade remove operations.
755
     *
756
     * @return boolean
757
     */
758 195
    private function isOrphanRemovalEnabled()
759
    {
760 195
        if ($this->mapping === null) {
761 11
            return false;
762
        }
763
764 184
        if (isset($this->mapping['embedded'])) {
765 109
            return true;
766
        }
767
768 81
        if (isset($this->mapping['reference']) && $this->mapping['isOwningSide'] && $this->mapping['orphanRemoval']) {
769 9
            return true;
770
        }
771
772 72
        return false;
773
    }
774
775
    /**
776
     * Checks whether collection owner needs to be scheduled for dirty change in case the collection is modified.
777
     *
778
     * @return bool
779
     */
780 203
    private function needsSchedulingForDirtyCheck()
781
    {
782 203
        return $this->owner && $this->dm && ! empty($this->mapping['isOwningSide'])
783 203
            && $this->dm->getClassMetadata(get_class($this->owner))->isChangeTrackingNotify();
784
    }
785
}
786