I tried to gather some information about the following way to delete automatically child entity when a parent entity is deleted. Seems that the most common way is to use one those three annotation: cascade={"remove"}
OR orphanRemoval=true
OR ondelete="CASCADE"
.
I am a bit confused about the third one: ondelete="CASCADE"
, as the explanation in doctrine official documentation about this one are very scarce) and I would love if someone could confirm me the following information I gathered and understand from my research on the net and experience...
What does it do?
cascade={"remove"}
==> the entity on the inverse side is deleted when the owning side entity is. Even if you are in a ManyToMany
with other owning side entity.
- should be used on collection (so in
OneToMany
or ManyToMany
relationship)
- implementation in the ORM
orphanRemoval=true
==> the entity on the inverse side is deleted when the owning side entity is AND it is not connected to any other owning side entity anymore. (ref. doctrine official_doc
- implementation in the ORM
- can be used with
OneToOne
, OneToMany
or ManyToMany
onDelete="CASCADE"
==> this will add On Delete Cascade to the foreign key column in the database
- This strategy is a bit tricky to get right but can be very powerful and fast. (ref. doctrine official_doc ... but haven't read more explanations)
- ORM has to do less work (compared to the two previous ways of doing it) and therefore should have better performance.
other information
- all those 3 ways of doing are implemented on bidirectional relationship entities (right???)
- using
cascade={"remove"}
completely by-passes any foreign key onDelete=CASCADE. (ref. doctrine_official_doc)
EXAMPLE ON HOW TO USE IT IN CODE
orphanRemoval
and cascade={"remove"}
are defined in the inversed entity class.
ondelete="CASCADE"
is defined in the owner entity
- you can also just write
@ORMJoinColumn(onDelete="CASCADE")
and let doctrine handle the column names
cascade={"remove"}
/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", cascade={"remove"})
*/
protected $Phonenumbers
orphanRemoval=true
/**
* @OneToMany(targetEntity="Phonenumber", mappedBy="contact", orphanRemoval=true)
*/
protected $Phonenumbers
onDelete="CASCADE"
/**
* @ManyToOne(targetEntity="Contact", inversedBy="phonenumbers")
* @JoinColumn(name="contact_id", referencedColumnName="contact_id", onDelete="CASCADE")
*/
protected $contact;
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…