ChatGPT解决这个技术问题 Extra ChatGPT

cascade={"remove"} VS orphanRemoval=true VS ondelete="CASCADE

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 @ORM\JoinColumn(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; 
it has a good explanation stackoverflow.com/questions/25515007/…

W
Waaghals

onDelete="CASCADE" is managed by the database itself. cascade={"remove"} is managed by doctrine.

onDelete="CASCADE" is faster because the operations are performed on database level instead by doctrine. The removing is performed by the database server and not Doctrine. With cascade={"remove"} doctrine has to manage the entity itself and will perform extra checks to see if it doesn't have any other owning entities. When no other exists it will delete the entity. But this creates overhead.

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. No, if the entity is owned by something else. It won't be deleted.

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. Not exactly, this makes doctrine behave like it is not owned by an other entity, and thus remove it.

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. (this is a quote from doctrine official tutorial... but haven't seen much more explaination)

ORM has to do less work (compared to the two previous way of doing) and therefore should have better performance.


@ waaghals. About your comments on the cascade={"remove"} ==> I have a ManyToMany relationship between entity Article and Category. When I remove an Article ($em->remove($article);) it does remove all categories linked to this article EVEN if those categories are also linked to other articles. so I would say that it does not behave as you write.
@ waaghals. About your comments on the orphanRemoval="true" The sentence I wrote "the entity on the inverse side is deleted when the owning side entity is, and it is not own by any other entities" is quoted from doctrine official pages. doctrine=orphanremoval.
@Alexis_D, fully agreed with your comments The answer is incorrect and can be really confusing for newbies
One of the clearer examples I've read: gist.github.com/pylebecq/f844d1f6860241d8b025
@VictorS' link is very clear. I'm no longer working with Doctrine so feel I cannot update my answer without knowing first hand how it works. If someone could update my answer that would be great.

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now