Skip to content

Commit 65b9940

Browse files
committed
Skip native lazy object initualisation for unmapped properties
1 parent a9eb0dd commit 65b9940

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

src/Proxy/Factory/NativeLazyObjectFactory.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
use Doctrine\Persistence\NotifyPropertyChanged;
1313
use LogicException;
1414
use ReflectionClass;
15+
use ReflectionProperty;
1516
use WeakMap;
1617

18+
use function array_key_exists;
1719
use function count;
1820

1921
use const PHP_VERSION_ID;
@@ -27,6 +29,9 @@ class NativeLazyObjectFactory implements ProxyFactory
2729
private readonly UnitOfWork $unitOfWork;
2830
private readonly LifecycleEventManager $lifecycleEventManager;
2931

32+
/** @var array<class-string, ReflectionProperty[]> */
33+
private array $skippedProperties = [];
34+
3035
public function __construct(
3136
DocumentManager $documentManager,
3237
) {
@@ -68,13 +73,36 @@ public function getProxy(ClassMetadata $metadata, $identifier): object
6873

6974
$metadata->propertyAccessors[$metadata->identifier]->setValue($proxy, $identifier);
7075

76+
foreach ($this->getSkippedProperties($metadata) as $property) {
77+
$property->skipLazyInitialization($proxy);
78+
}
79+
7180
if (isset(self::$lazyObjects)) {
7281
self::$lazyObjects[$proxy] = true;
7382
}
7483

7584
return $proxy;
7685
}
7786

87+
/** @return ReflectionProperty[] */
88+
private function getSkippedProperties(ClassMetadata $metadata): array
89+
{
90+
if (isset($this->skippedProperties[$metadata->name])) {
91+
return $this->skippedProperties[$metadata->name];
92+
}
93+
94+
$skippedProperties = [];
95+
foreach ($metadata->reflClass->getProperties() as $property) {
96+
if (array_key_exists($property->name, $metadata->propertyAccessors)) {
97+
continue;
98+
}
99+
100+
$skippedProperties[] = $property;
101+
}
102+
103+
return $this->skippedProperties[$metadata->name] = $skippedProperties;
104+
}
105+
78106
/** @internal Only for tests */
79107
public static function enableTracking(bool $enabled = true): void
80108
{

tests/Tests/Functional/ReferencesTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Doctrine\ODM\MongoDB\Tests\BaseTestCase;
1616
use Documents\Account;
1717
use Documents\Address;
18+
use Documents\DocumentWithUnmappedProperties;
1819
use Documents\Group;
1920
use Documents\Phonenumber;
2021
use Documents\Profile;
@@ -28,6 +29,15 @@
2829

2930
class ReferencesTest extends BaseTestCase
3031
{
32+
public function testSkipInitializationForUnmappedProperties(): void
33+
{
34+
$loadedDocument = $this->dm->getReference(DocumentWithUnmappedProperties::class, '123');
35+
$this->assertInstanceOf(DocumentWithUnmappedProperties::class, $loadedDocument);
36+
37+
// Accessing unmapped property should not initialize the document
38+
self::assertSame('bar', $loadedDocument->foo);
39+
}
40+
3141
public function testManyDeleteReference(): void
3242
{
3343
$user = new User();

0 commit comments

Comments
 (0)