我试着收集了一些和 “删除父entity时,子entity也被自动删除” 有关的、应当遵循的信息。最常见的方式是使用以下三种annotation之一:cascade={“remove”},或是 orphanRemoval=true,或是 ondelete=”CASCADE”。
cascade={“remove”}
/**
* @OneToMany(targetEntity="B", mappedBy="A", cascade={"remove"})
*/
protected $B
如果实体A包含实体B,删除实体A,Doctrine也会删除collection中的所有B实体。
使用此种方法很方便,但也应该小心使用,因为在级联删除中会将对象拖入内存会导致相当大的性能开销,尤其是当级联集合
很大时。
比如:你的User有一对多的关系Comment。如果你正在使用cascade=”remove”,您可以从一个User,删除关联的Comment。也可以再之后将Comment附到另一个User上。当你persist他们时,他们将被正确保存。
orphanRemoval=true
/**
* @OneToMany(targetEntity="B", mappedBy="A", orphanRemoval=true)
*/
protected $B
与cascade={"remove"}
类似,但也有自己的特点。如果实体A包含对私有实体B的引用,那么如果从中删除引用A,则该实体B也应被删除,因为它不再被使用。
使用orphanRemoval=true选项时,Doctrine假设实体是私有的,也就是不会被其他实体重用。如果您忽略了这个假设,即使您将一个独立出来的实体分配给另一个实体,您的实体也会被Doctrine删除。
比如:你的User有一对多的关系Comment。如果你正在使用cascade=”remove”,您可以从一个User,删除关联的Comment,然后附上Comment到另一个User。当你persist他们时,他们将被正确保存。但是如果您正在使用orphanRemoval=true,即使您从一个User中的删除Comment,然后将其附加到另一个User,此Comment最终还是会在持久化期间被删除,因为该关联已被删除。
ondelete=”CASCADE”
/**
* @ManyToOne(targetEntity="A", inversedBy="B")
* @JoinColumn(name="A_id", referencedColumnName="A_id", onDelete="CASCADE")
*/
protected $A;
更快是因为该操作在数据库层面进行,而非在doctrine中进行。其删除动作由数据库服务器来完成,而不是doctrine。