Skip to content

Change default tracking policy for "deferred explicit" #11961

Open
@Pierstoval

Description

@Pierstoval

Current default Tracking policy is set to "deferred implicit", has been since the beginning, meaning all objects retrieved from repositories are stored in the UnitOfWork for potential updates/deletions for the next call to em->flush or uow->commit

However, I stopped counting the amount of Symfony+Doctrine projects I worked on that suffered from that on two specific levels:

  • Performances suffer when big loads of entities are loaded because of all the comparisons, entities in memory, etc.
  • Side-effects are largely numerous because one single $em->flush() will trigger all the cascading checks for entities updates and deletions

Whenever we encounter performance issues for that, the usual solution is to run the updates in batches, but even then, sometimes you have a batch of entities on which only a percentage need to be actually updated, meaning we lose performances on all other changesets checks and comparisons.

And for the side-effects, I blame the default anemic-objects behavior that most documentations have been recommending for years, because updates on anemic entities can happen anywhere without validation, and the main place I found these were when Symfony Forms were used with Doctrine Entities.
Even though Symfony Forms trigger validation on submit to ensure "one will not persist it", a big bunch of legacy apps still use kernel or doctrine events for other kinds of usages that might call a flush() somewhere.
It can definitely happen in 3rd-party libs, even though the most popular ones usually take care, but we're never sure, will never be, and all the legacy apps in the world using the old-recommended event-based coding practice will encounter this some day. Even EasyAdmin forgot to call "persist()" on update at some point, meaning the whole "Doctrine persists by default" is deeply anchored to devs' minds, even the ones of the most talented and active in the Symfony ecosystem.

Changing the default tracking policy in a major version, and adding a migration path (i.e "A deprecation message recommending to set the annotation manually on each entity", maybe followed by some static analysers, hopefully) will help devs understand more how Doctrine works, and if they decide to keep the "implicit" behavior, they will know what to expect, especially if they migrated using Rector or similar tools that enforce them to explicitly define the PHP attribute to configure the tracking policy.
Conjointedly, the policy could be configurable directly in the Entity annotation in a minor version instead of having its own attribute, to help for better discovery, curiosity and understanding of this concept.

Of course this sounds like a big change, but it's quite as big as the removal of single-entity flush, or removal of the "notify" strategy in ORM v4, for example, but if this is ever accepted at some point, I'm willing to help working on it, since I've been promoting this for a long time.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions