Skip to content

Commit e8275f6

Browse files
Removing list "Lifecycle Events" (#9243)
As announced in #9184 (comment)
1 parent 6a9393e commit e8275f6

File tree

2 files changed

+88
-130
lines changed

2 files changed

+88
-130
lines changed

docs/en/reference/events.rst

Lines changed: 86 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ or ``eventManager->addEventSubscriber()``, see
132132
* *Lifecycle Callbacks* can also be registered in the entity mapping (annotation, attribute, etc.),
133133
see :ref:`Lifecycle Callbacks<lifecycle-callbacks>`
134134

135+
.. _reference-events-lifecycle-events:
136+
135137
Events Overview
136138
---------------
137139

@@ -165,7 +167,7 @@ Events Overview
165167
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
166168
| :ref:`postFlush<reference-events-post-flush>` | ``$em->flush()`` | No | `_PostFlushEventArgs` |
167169
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
168-
| ``onClear`` | ``$em->clear()`` | No | `_OnClearEventArgs` |
170+
| :ref:`onClear<reference-events-on-clear>` | ``$em->clear()`` | No | `_OnClearEventArgs` |
169171
+-----------------------------------------------------------------+-----------------------+-----------+-------------------------------------+
170172

171173
Naming convention
@@ -187,94 +189,6 @@ several reasons:
187189
An example for a correct notation can be found in the example
188190
``TestEvent`` above.
189191

190-
.. _reference-events-lifecycle-events:
191-
192-
Lifecycle Events
193-
----------------
194-
195-
The ``EntityManager`` and ``UnitOfWork`` classes trigger a bunch of
196-
events during the life-time of their registered entities.
197-
198-
199-
200-
- ``preRemove`` - The ``preRemove`` event occurs for a given entity
201-
before the respective ``EntityManager`` remove operation for that
202-
entity is executed. It is not called for a DQL ``DELETE`` statement.
203-
- ``postRemove`` - The ``postRemove`` event occurs for an entity after the
204-
entity has been deleted. It will be invoked after the database
205-
delete operations. It is not called for a DQL ``DELETE`` statement.
206-
- ``prePersist`` - The ``prePersist`` event occurs for a given entity
207-
before the respective ``EntityManager`` persist operation for that
208-
entity is executed. It should be noted that this event is only triggered on
209-
*initial* persist of an entity (i.e. it does not trigger on future updates).
210-
- ``postPersist`` - The ``postPersist`` event occurs for an entity after
211-
the entity has been made persistent. It will be invoked after the
212-
database insert operations. Generated primary key values are
213-
available in the postPersist event.
214-
- ``preUpdate`` - The ``preUpdate`` event occurs before the database
215-
update operations to entity data. It is not called for a DQL
216-
``UPDATE`` statement nor when the computed changeset is empty.
217-
- ``postUpdate`` - The ``postUpdate`` event occurs after the database
218-
update operations to entity data. It is not called for a DQL
219-
``UPDATE`` statement.
220-
- ``postLoad`` - The postLoad event occurs for an entity after the
221-
entity has been loaded into the current ``EntityManager`` from the
222-
database or after the refresh operation has been applied to it.
223-
- ``loadClassMetadata`` - The ``loadClassMetadata`` event occurs after the
224-
mapping metadata for a class has been loaded from a mapping source
225-
(annotations/xml/yaml). This event is not a lifecycle callback.
226-
- ``onClassMetadataNotFound`` - Loading class metadata for a particular
227-
requested class name failed. Manipulating the given event args instance
228-
allows providing fallback metadata even when no actual metadata exists
229-
or could be found. This event is not a lifecycle callback.
230-
- ``preFlush`` - The ``preFlush`` event occurs at the very beginning of
231-
a flush operation.
232-
- ``onFlush`` - The ``onFlush`` event occurs after the change-sets of all
233-
managed entities are computed. This event is not a lifecycle
234-
callback.
235-
- ``postFlush`` - The ``postFlush`` event occurs at the end of a flush operation. This
236-
event is not a lifecycle callback.
237-
- ``onClear`` - The ``onClear`` event occurs when the
238-
``EntityManager#clear()`` operation is invoked, after all references
239-
to entities have been removed from the unit of work. This event is not
240-
a lifecycle callback.
241-
242-
243-
.. warning::
244-
245-
Note that, when using ``Doctrine\ORM\AbstractQuery#toIterable()``, ``postLoad``
246-
events will be executed immediately after objects are being hydrated, and therefore
247-
associations are not guaranteed to be initialized. It is not safe to combine
248-
usage of ``Doctrine\ORM\AbstractQuery#toIterable()`` and ``postLoad`` event
249-
handlers.
250-
251-
.. warning::
252-
253-
Note that the ``postRemove`` event or any events triggered after an entity removal
254-
can receive an uninitializable proxy in case you have configured an entity to
255-
cascade remove relations. In this case, you should load yourself the proxy in
256-
the associated pre event.
257-
258-
These can be hooked into by two different types of event
259-
listeners:
260-
261-
- Lifecycle Callbacks are methods on the entity classes that are
262-
called when the event is triggered. They receive some kind
263-
of ``EventArgs`` instance.
264-
- Lifecycle Event Listeners and Subscribers are classes with specific callback
265-
methods that receives some kind of ``EventArgs`` instance.
266-
267-
The ``EventArgs`` instance received by the listener gives access to the entity,
268-
``EntityManager`` instance and other relevant data.
269-
270-
.. note::
271-
272-
All Lifecycle events that happen during the ``flush()`` of
273-
an ``EntityManager`` have very specific constraints on the allowed
274-
operations that can be executed. Please read the
275-
:ref:`reference-events-implementing-listeners` section very carefully
276-
to understand which operations are allowed in which lifecycle event.
277-
278192
.. _lifecycle-callbacks:
279193

280194
Lifecycle Callbacks
@@ -300,10 +214,8 @@ specific to a particular entity class's lifecycle.
300214
use Doctrine\DBAL\Types\Types;
301215
use Doctrine\Persistence\Event\LifecycleEventArgs;
302216
303-
/**
304-
* #[Entity]
305-
* #[HasLifecycleCallbacks]
306-
*/
217+
#[Entity]
218+
#[HasLifecycleCallbacks]
307219
class User
308220
{
309221
// ...
@@ -538,37 +450,41 @@ that (prior to version 2.4) you do not have access to the
538450
prePersist
539451
~~~~~~~~~~
540452

541-
There are two ways for the ``prePersist`` event to be triggered.
542-
One is obviously when you call ``EntityManager#persist()``. The
543-
event is also called for all cascaded associations.
453+
There are two ways for the ``prePersist`` event to be triggered:
544454

545-
There is another way for ``prePersist`` to be called, inside the
455+
- One is obviously when you call ``EntityManager::persist()``. The
456+
event is also called for all :ref:`cascaded associations<transitive-persistence>`.
457+
- The other is inside the
546458
``flush()`` method when changes to associations are computed and
547-
this association is marked as cascade persist. Any new entity found
459+
this association is marked as :ref:`cascade: persist<transitive-persistence>`. Any new entity found
548460
during this operation is also persisted and ``prePersist`` called
549-
on it. This is called "persistence by reachability".
461+
on it. This is called :ref:`persistence by reachability<persistence-by-reachability>`.
550462

551463
In both cases you get passed a ``LifecycleEventArgs`` instance
552464
which has access to the entity and the entity manager.
553465

554-
The following restrictions apply to ``prePersist``:
466+
This event is only triggered on *initial* persist of an entity
467+
(i.e. it does not trigger on future updates).
555468

469+
The following restrictions apply to ``prePersist``:
556470

557471
- If you are using a PrePersist Identity Generator such as
558472
sequences the ID value will *NOT* be available within any
559473
PrePersist events.
560474
- Doctrine will not recognize changes made to relations in a prePersist
561475
event. This includes modifications to
562476
collections such as additions, removals or replacement.
563-
477+
564478
.. _reference-events-pre-remove:
565479

566480
preRemove
567481
~~~~~~~~~
568482

569-
The ``preRemove`` event is called on every entity when its passed
570-
to the ``EntityManager#remove()`` method. It is cascaded for all
571-
associations that are marked as cascade delete.
483+
The ``preRemove`` event is called on every entity immediately when it is passed
484+
to the ``EntityManager::remove()`` method. It is cascaded for all
485+
associations that are marked as :ref:`cascade: remove<transitive-persistence>`
486+
487+
It is not called for a DQL ``DELETE`` statement.
572488

573489
There are no restrictions to what methods can be called inside the
574490
``preRemove`` event, except when the remove method itself was
@@ -579,10 +495,10 @@ called during a flush operation.
579495
preFlush
580496
~~~~~~~~
581497

582-
``preFlush`` is called at ``EntityManager#flush()`` before
583-
anything else. ``EntityManager#flush()`` should not be called inside
584-
its listeners, since `preFlush` event is dispatched in it, which would
585-
result in infinite loop.
498+
``preFlush`` is called inside ``EntityManager::flush()`` before
499+
anything else. ``EntityManager::flush()`` must not be called inside
500+
its listeners, since it would fire the ``preFlush`` event again, which would
501+
result in an infinite loop.
586502

587503
.. code-block:: php
588504
@@ -603,20 +519,19 @@ result in infinite loop.
603519
onFlush
604520
~~~~~~~
605521

606-
OnFlush is a very powerful event. It is called inside
607-
``EntityManager#flush()`` after the changes to all the managed
522+
``onFlush`` is a very powerful event. It is called inside
523+
``EntityManager::flush()`` after the changes to all the managed
608524
entities and their associations have been computed. This means, the
609525
``onFlush`` event has access to the sets of:
610526

611-
612527
- Entities scheduled for insert
613528
- Entities scheduled for update
614529
- Entities scheduled for removal
615530
- Collections scheduled for update
616531
- Collections scheduled for removal
617532

618533
To make use of the ``onFlush`` event you have to be familiar with the
619-
internal ``UnitOfWork`` API, which grants you access to the previously
534+
internal :ref:`UnitOfWork<unit-of-work>` API, which grants you access to the previously
620535
mentioned sets. See this example:
621536

622537
.. code-block:: php
@@ -651,11 +566,10 @@ mentioned sets. See this example:
651566
}
652567
}
653568
654-
The following restrictions apply to the onFlush event:
655-
569+
The following restrictions apply to the ``onFlush`` event:
656570

657571
- If you create and persist a new entity in ``onFlush``, then
658-
calling ``EntityManager#persist()`` is not enough.
572+
calling ``EntityManager::persist()`` is not enough.
659573
You have to execute an additional call to
660574
``$unitOfWork->computeChangeSet($classMetadata, $entity)``.
661575
- Changing primitive fields or associations requires you to
@@ -668,8 +582,9 @@ The following restrictions apply to the onFlush event:
668582
postFlush
669583
~~~~~~~~~
670584

671-
``postFlush`` is called at the end of ``EntityManager#flush()``.
672-
``EntityManager#flush()`` can **NOT** be called safely inside its listeners.
585+
``postFlush`` is called at the end of ``EntityManager::flush()``.
586+
``EntityManager::flush()`` can **NOT** be called safely inside its listeners.
587+
This event is not a lifecycle callback.
673588

674589
.. code-block:: php
675590
@@ -690,22 +605,22 @@ postFlush
690605
preUpdate
691606
~~~~~~~~~
692607

693-
PreUpdate is called inside the ``EntityManager#flush()`` method,
608+
PreUpdate is called inside the ``EntityManager::flush()`` method,
694609
right before an SQL ``UPDATE`` statement. This event is not
695-
triggered when the computed changeset is empty.
610+
triggered when the computed changeset is empty, nor for a DQL
611+
``UPDATE`` statement.
696612

697613
Changes to associations of the updated entity are never allowed in
698614
this event, since Doctrine cannot guarantee to correctly handle
699615
referential integrity at this point of the flush operation. This
700616
event has a powerful feature however, it is executed with a
701-
``PreUpdateEventArgs`` instance, which contains a reference to the
617+
`_PreUpdateEventArgs`_ instance, which contains a reference to the
702618
computed change-set of this entity.
703619

704620
This means you have access to all the fields that have changed for
705621
this entity with their old and new value. The following methods are
706622
available on the ``PreUpdateEventArgs``:
707623

708-
709624
- ``getEntity()`` to get access to the actual entity.
710625
- ``getEntityChangeSet()`` to get a copy of the changeset array.
711626
Changes to this returned array do not affect updating.
@@ -759,15 +674,14 @@ lifecycle callback when there are expensive validations to call:
759674
760675
Restrictions for this event:
761676

762-
763677
- Changes to associations of the passed entities are not
764678
recognized by the flush operation anymore.
765679
- Changes to fields of the passed entities are not recognized by
766680
the flush operation anymore, use the computed change-set passed to
767681
the event to modify primitive field values, e.g. use
768682
``$eventArgs->setNewValue($field, $value);`` as in the Alice to Bob example above.
769-
- Any calls to ``EntityManager#persist()`` or
770-
``EntityManager#remove()``, even in combination with the ``UnitOfWork``
683+
- Any calls to ``EntityManager::persist()`` or
684+
``EntityManager::remove()``, even in combination with the ``UnitOfWork``
771685
API are strongly discouraged and don't work as expected outside the
772686
flush operation.
773687

@@ -776,19 +690,54 @@ Restrictions for this event:
776690
postUpdate, postRemove, postPersist
777691
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
778692

779-
The three post events are called inside ``EntityManager#flush()``.
693+
These three post* events are called inside ``EntityManager::flush()``.
780694
Changes in here are not relevant to the persistence in the
781695
database, but you can use these events to alter non-persistable items,
782696
like non-mapped fields, logging or even associated classes that are
783697
not directly mapped by Doctrine.
784698

699+
- The ``postUpdate`` event occurs after the database
700+
update operations to entity data. It is not called for a DQL
701+
``UPDATE`` statement.
702+
- The ``postPersist`` event occurs for an entity after
703+
the entity has been made persistent. It will be invoked after the
704+
database insert operations. Generated primary key values are
705+
available in the postPersist event.
706+
- The ``postRemove`` event occurs for an entity after the
707+
entity has been deleted. It will be invoked after the database
708+
delete operations. It is not called for a DQL ``DELETE`` statement.
709+
710+
.. warning::
711+
712+
The ``postRemove`` event or any events triggered after an entity removal
713+
can receive an uninitializable proxy in case you have configured an entity to
714+
cascade remove relations. In this case, you should load yourself the proxy in
715+
the associated ``pre*`` event.
716+
785717
.. _reference-events-post-load:
786718

787719
postLoad
788720
~~~~~~~~
789721

790-
This event is called after an entity is constructed by the
791-
EntityManager.
722+
The postLoad event occurs after the entity has been loaded into the current
723+
``EntityManager`` from the database or after ``refresh()`` has been applied to it.
724+
725+
.. warning::
726+
727+
When using ``Doctrine\ORM\AbstractQuery::toIterable()``, ``postLoad``
728+
events will be executed immediately after objects are being hydrated, and therefore
729+
associations are not guaranteed to be initialized. It is not safe to combine
730+
usage of ``Doctrine\ORM\AbstractQuery::toIterable()`` and ``postLoad`` event
731+
handlers.
732+
733+
.. _reference-events-on-clear:
734+
735+
onClear
736+
~~~~~~~~
737+
738+
The ``onClear`` event occurs when the ``EntityManager::clear()`` operation is invoked,
739+
after all references to entities have been removed from the unit of work.
740+
This event is not a lifecycle callback.
792741

793742
Entity listeners
794743
----------------
@@ -1013,9 +962,11 @@ Implementing your own resolver :
1013962
Load ClassMetadata Event
1014963
------------------------
1015964

1016-
When the mapping information for an entity is read, it is populated
1017-
in to a ``Doctrine\ORM\Mapping\ClassMetadata`` instance. You can hook in to this
1018-
process and manipulate the instance.
965+
``loadClassMetadata`` - The ``loadClassMetadata`` event occurs after the
966+
mapping metadata for a class has been loaded from a mapping source
967+
(annotations/xml/yaml) in to a ``Doctrine\ORM\Mapping\ClassMetadata`` instance.
968+
You can hook in to this process and manipulate the instance.
969+
This event is not a lifecycle callback.
1019970

1020971
.. code-block:: php
1021972
@@ -1038,6 +989,11 @@ process and manipulate the instance.
1038989
}
1039990
}
1040991
992+
If not class metadata can be found, an ``onClassMetadataNotFound`` event is dispatched.
993+
Manipulating the given event args instance
994+
allows providing fallback metadata even when no actual metadata exists
995+
or could be found. This event is not a lifecycle callback.
996+
1041997
SchemaTool Events
1042998
-----------------
1043999

docs/en/reference/working-with-associations.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,8 @@ For each cascade operation that gets activated, Doctrine also
521521
applies that operation to the association, be it single or
522522
collection valued.
523523

524+
.. _persistence-by-reachability:
525+
524526
Persistence by Reachability: Cascade Persist
525527
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
526528

0 commit comments

Comments
 (0)