/test-doctrine-postload-event-loading-reference

Demonstration on PostLoad listeners not being triggered when loading entities via reference

Primary LanguagePHP

Demonstration of PostLoad events not being triggered when retrieving objects by reference

Usage

This application requires an executable file bin/php that loads the correct PHP binary (as generated by our internal tool phlough on phlough install).

First, install dependencies and create a new database with the correct schema (will create an SQLite database in ./tmp)

composer install

bin/doctrine orm:schema-tool:create

Create an Entity and load it normally

bin/create-new-entity # assume it creates an entity with id 1
bin/load-entity 1 # Output should contain: PostLoad EventListener called for Entity\Test#1

Load the same entity by reference and access a property to trigger initialisation

bin/load-entity-by-reference-and-access-proprty 1 # Will the output contain: "PostLoad EventListener called"?

This repository is there to change the implementation around (upgrade/downgrade Doctrine versions, change the configuration in EntityManagerFactory, use different kinds of properties in the Test entity) and test how initialisation/PostLoad event behaviour changes.

Explanation

When loading an entity by reference, whether the object will be initialised on a method call or property access depends on the implementation of uninitialised object. Using either doctrine/orm 2.x or 3.x, there are 3 possible implementations:

Proxy using Doctrines Proxy Generator (doctrine 2.x default, gone in doctrine 3.x)

Proxies will be initialised on method calls.

See doctrine/DoctrineBundle#1651 (comment)

"Lazy Ghost Object" using Symfony's VarExporter\LazyGhostTrait (doctrine 3.x default)

Proxies will be initialised only when accessing mapped properties. This could become a problem if you want to initialise an unmapped property via the PostLoad event.

See doctrine/DoctrineBundle#1651 (comment)

However, using this repository, we found out that this is not true for unmapped properties inside Embeddables: Access to unmapped properties inside Embeddables will trigger initialisation (unlike unmapped properties directly on the Entity).

PHP 8.4 Native lazy objects (requires PHP 8.4+ and doctrine/orm 3.x and $config->enableNativeLazyObjects(true);)

Could not test as we have no PHP 8.4 environment yet.

https://www.php.net/manual/en/language.oop5.lazy-objects.php#language.oop5.lazy-objects.initialization-triggers implies that access to all properties (mapped and unmapped) will trigger initialisation.