假设我们有两个实体(Profile
和Address
)。一个配置文件可以有许多地址。在这种情况下,我们有:
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
现在,如果我删除一个有很多地址的配置文件:
$em->remove($profile);
如何删除地址?
Doctrine是提取与该配置文件相关的所有地址,然后删除它们,还是只删除配置文件,让数据库处理地址?
我找到了一些关于Hibernate的答案,但没有找到关于条令。
编辑:添加条令书籍中的三个注释
1.如果关联被标记为CASCADE=REMOVE,则条令2将获取该关联。如果它是单一关联,它将把这个实体传递给
EntityManager#remove()
。如果关联是一个集合,则条令将遍历其所有元素,并将它们传递给EntityManager#remove()
。在这两种情况下,级联移除语义都是递归应用的。对于大型对象图,这种删除策略可能非常昂贵。2.使用DQL DELETE语句可以使用单个命令删除同一类型的多个实体,而无需对这些实体进行水合。这可以非常有效地从数据库中删除大型对象图。
3.使用外键语义onDelete=";级联";可以强制数据库在内部删除所有关联的对象。这种策略有点棘手,但可能非常强大和快速但是,您应该注意,使用策略1(
CASCADE=REMOVE
)完全绕过任何外键onDelete=CASCADE
选项,因为Doctrine将明确获取和删除所有相关实体。
我做了一个测试:
我首先获取Profile
(只有profile
,没有join)并将其传递给$em->remove($profile)
,然后原则运行另一个查询,获取与Profile
相关的所有Address
(一个查询),然后,理论对与Profile
相关的每个地址运行删除查询,最后删除Profile
。
因此,我可以说orphanRemoval是另一种级联,正如学说所说:
orphanRemoval:级联的另一个概念只有在从集合中删除实体时才相关
和orphanRemoval
绕过onDelete
。
条令手册中有一节关于孤儿移除。还有一个问题澄清了onDelete: cascade
。我希望这两个链接能帮助你进一步理解这个话题。
此外,请确保在$em->remove($profile);
之后调用$em->flush();
操作以将本地工作单元同步到数据库。