Does orphanRemoval bypass onDelete?
Assume that we have two entities ( Profile
and Address
). A profile can have many addresses. In that case we have:
Profile:
...
fields:
...
oneToMany:
addresses:
targetEntity: Address
mappedBy: profile
orphanRemoval: true
Address:
...
fields:
...
manyToOne:
profile:
targetEntity: Profile
inversedBy: addresses
joinColumn:
name: profile_id
referencedColumnName: id
onDelete: cascade
Now, if I delete a profile that has many addresses:
$em->remove($profile);
How do the addresses get deleted?
Does Doctrine fetch all the addresses that are related to this profile and then delete them or does it only delete the profile and let the database handle the addresses?
I've found a few answers regarding Hibernate , but nothing about Doctrine .
EDIT : Add three note from Doctrine book
1.If an association is marked as CASCADE=REMOVE Doctrine 2 will fetch this association. If its a Single association it will pass this entity to EntityManager#remove()
. If the association is a collection, Doctrine will loop over all its elements and pass them to EntityManager#remove()
. In both cases the cascade remove semantics are applied recursively. For large object graphs this removal strategy can be very costly.
2.Using a DQL DELETE statement allows you to delete multiple entities of a type with a single command and without hydrating these entities. This can be very efficient to delete large object graphs from the database.
3.Using foreign key semantics onDelete="CASCADE" can force the database to remove all associated objects internally. This strategy is a bit tricky to get right but can be very powerful and fast. You should be aware however that using strategy 1 ( CASCADE=REMOVE
) completely by-passes any foreign key onDelete=CASCADE
option , because Doctrine will fetch and remove all associated entities explicitly nevertheless.
I do a test:
I first fetch Profile
( only profile
without join ) and pass it to $em->remove($profile)
, then doctrine run a another query that fetch all Address
that related to Profile
(one query) and after it, doctrine run a delete query for each address that related to Profile
, and in the final it delete Profile
.
so, i can say that orphanRemoval is another type of cascading , as doctrine say:
orphanRemoval : There is another concept of cascading that is relevant only when removing entities from collections
and orphanRemoval
bypass onDelete
.
There is a section on orphan removal in the Doctrine manual. There is also another question clarifying onDelete: cascade
. I hope the two links help you further understand the topic.
Also, make sure that after $em->remove($profile);
you call the $em->flush();
operation to sync the local unit of work to the database.
上一篇: 创建和定位浮动操作按钮