Skip to content

Conversation

@greg0ire
Copy link
Member

@greg0ire greg0ire commented Jan 6, 2026

Initializing e.g. a readonly ID does not require loading any data from
the database. However, calling isInitialized() on the reflection of a
readonly property triggers the native lazy object initialization.
If we have a lazy property at hand, then the property cannot be initialized
already, so it is safe to skip the call.

Fixes #12166

public function testProxyWithReadonlyIdIsNotInitializedImmediately(): void
{
if (! $this->_em->getConfiguration()->isNativeLazyObjectsEnabled()) {
$this->markTestSkipped('Property hooks require native lazy objects to be enabled.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This skipping looks weird to me. This test does not rely on property hooks

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, sorry, I copied it from somewhere and failed to adapt the message.

$id = $proxy->getId();
self::assertSame(123, $id);
self::assertTrue(
$reflClass->isUninitializedLazyObject($proxy),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the dedicated method of the base test case should allow making this test compatible with old proxy systems

use Doctrine\Tests\OrmFunctionalTestCase;
use PHPUnit\Framework\Attributes\RequiresPhp;

#[RequiresPhp('>= 8.4.0')]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be necessary anymore if we execute the test with all proxy implementations

SenseException
SenseException previously approved these changes Jan 6, 2026
Copy link
Member

@SenseException SenseException left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is okay for handling the lazy-loading, but if I remove your newly added code, the test fails with a message like "no such table: gh12166_lazy_entity", because it tries to access a table that doesn't exist (and doesn't need to since the test uses a Reference). This can be confusing if a regression happens during future development.

@greg0ire greg0ire force-pushed the gh-12166 branch 2 times, most recently from 10489bc to 459bac6 Compare January 7, 2026 06:53
@greg0ire greg0ire marked this pull request as draft January 7, 2026 06:54
@greg0ire greg0ire force-pushed the gh-12166 branch 2 times, most recently from fa3832c to a4dc09d Compare January 7, 2026 07:03
@greg0ire
Copy link
Member Author

greg0ire commented Jan 7, 2026

This is okay for handling the lazy-loading, but if I remove your newly added code, the test fails with a message like "no such table: gh12166_lazy_entity", because it tries to access a table that doesn't exist (and doesn't need to since the test uses a Reference). This can be confusing if a regression happens during future development.

Good point, addressed.

@greg0ire greg0ire marked this pull request as ready for review January 7, 2026 07:33
@stof
Copy link
Member

stof commented Jan 7, 2026

Maybe this should use the ReflectionProperty::isLazy method, to skip this check check only for lazy properties, to avoid assigning values multiple times in readonly properties that are already initialized (which is the reason why this special access exists).

Initializing e.g. a readonly ID does not require loading any data from
the database. However, calling isInitialized() on the reflection of a
readonly property triggers the native lazy object initialization.
If we have a lazy property at hand, then the property cannot be initialized
already, so it is safe to skip the call.
@greg0ire
Copy link
Member Author

greg0ire commented Jan 7, 2026

@stof I did not know about that method, thanks for pointing it out! It makes the code smaller, so I've combined both if statements into one, and it will further simplify in 4.0.x because we will be able to drop the PHP version id check.

I've also been able to remove the word "assume" from the commit message and PR description, which feels good.

@stof
Copy link
Member

stof commented Jan 7, 2026

I did not know about that method, thanks for pointing it out!

I just discovered now actually.

@greg0ire greg0ire added the Bug label Jan 9, 2026
@greg0ire greg0ire added this to the 3.6.1 milestone Jan 9, 2026
@greg0ire greg0ire merged commit 2148940 into doctrine:3.6.x Jan 9, 2026
109 checks passed
@greg0ire greg0ire deleted the gh-12166 branch January 9, 2026 05:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug in readonly properties & native lazy objects, triggers immedtiately

3 participants