/doctrine-orm-dangerous-edge-cases

Less known yet dangerous doctrine/orm edge-cases

Primary LanguagePHP

Dangerous Doctrine edge-cases you should know about

  1. Avoid #[OneToOne] relationships (performance issue)
  2. Beware of Entity Inheritance (performance issue)
  3. Do not introduce complex logic to $entity->get*EntityIdentifier* (performance issue)
  4. Private methods do not trigger Doctrine\ORM\Proxy->__load (consistency failure)
  5. Do not reassign Collections, use $collection->clear() (consistency issue)
  6. Beware of cascade persist (consistency issue)
  7. Do not introduce __toString() on Entity classes (consistency issue)

All examples include the Problem subdirectory with the code that will fail and the Solution subdirectory with the code that will work. Check tests directory for the tests that prove the examples.

Additional less known issues without example in this repository

  1. Abstract classes must be part of #[DiscriminatorMap] even though they are in the middle of hierarchy (doctrine/orm#9142)
  2. Avoid Collection::matching (https://rnd.shipmonk.com/avoid-using-doctrines-collectionmatching-method)

Understanding illustrated issues

In order to understand the issues, you need to understand how Doctrine works. Most issues are either related to lib/Doctrine/ORM/UnitOfWork or generated proxies. To see generated proxies, run vendor/bin/doctrine orm:generate-proxies and then check the var/cache/doctrine/ directory.

Local setup

You need docker and docker compose v2 installed.

Test locally

  • printf "UID=$(id -u)\nGID=$(id -g)" > .env (optional, sets up permissions for the shared folders on linux. Requires direnv to apply automatically)
  • docker compose up -d
  • docker compose run -it app bash
  • composer install && composer prepare-database
  • composer test -> Some tests are supposed to fail, you're supposed experiment with those cases individually