@@ -286,17 +286,53 @@ as follows:
286
286
After an entity has been removed, its in-memory state is the same as
287
287
before the removal, except for generated identifiers.
288
288
289
- Removing an entity will also automatically delete any existing
290
- records in many-to-many join tables that link this entity. The
291
- action taken depends on the value of the ``@joinColumn `` mapping
292
- attribute "onDelete". Either Doctrine issues a dedicated ``DELETE ``
293
- statement for records of each join table or it depends on the
294
- foreign key semantics of onDelete="CASCADE".
289
+ During the ``EntityManager#flush() `` operation, the removed entity
290
+ will also be removed from all collections in entities currently
291
+ loaded into memory.
292
+
293
+ .. _remove_object_many_to_many_join_tables :
294
+
295
+ Join-table management when removing from many-to-many collections
296
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
297
+
298
+ Regarding existing rows in many-to-many join tables that refer to
299
+ an entity being removed, the following applies.
300
+
301
+ When the entity being removed does not declare the many-to-many association
302
+ itself (that is, the many-to-many association is unidirectional and
303
+ the entity is on the inverse side), the ORM has no reasonable way to
304
+ detect associations targeting the entity's class. Thus, no ORM-level handling
305
+ of join-table rows is attempted and database-level constraints apply.
306
+ In case of database-level ``ON DELETE RESTRICT `` constraints, the
307
+ ``EntityManager#flush() `` operation may abort and a ``ConstraintViolationException ``
308
+ may be thrown. No in-memory collections will be modified in this case.
309
+ With ``ON DELETE CASCADE ``, the RDBMS will take care of removing rows
310
+ from join tables.
311
+
312
+ When the entity being removed is part of bi-directional many-to-many
313
+ association, either as the owning or inverse side, the ORM will
314
+ delete rows from join tables before removing the entity itself. That means
315
+ database-level ``ON DELETE RESTRICT `` constraints on join tables are not
316
+ effective, since the join table rows are removed first. Removal of join table
317
+ rows happens through specialized methods in entity and collection persister
318
+ classes and take one query per entity and join table. In case the association
319
+ uses a ``@JoinColumn `` configuration with ``onDelete="CASCADE" ``, instead
320
+ of using a dedicated ``DELETE `` query the database-level operation will be
321
+ relied upon.
322
+
323
+ .. note ::
324
+
325
+ In case you rely on database-level ``ON DELETE RESTRICT `` constraints,
326
+ be aware that by making many-to-many associations bidirectional the
327
+ assumed protection may be lost.
328
+
329
+
330
+ Performance of different deletion strategies
331
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
295
332
296
333
Deleting an object with all its associated objects can be achieved
297
334
in multiple ways with very different performance impacts.
298
335
299
-
300
336
1. If an association is marked as ``CASCADE=REMOVE `` Doctrine ORM
301
337
will fetch this association. If its a Single association it will
302
338
pass this entity to
0 commit comments