orphanRemove是否绕过onDelete



假设我们有两个实体(ProfileAddress)。一个配置文件可以有许多地址。在这种情况下,我们有:

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();操作以将本地工作单元同步到数据库。

相关内容

  • 没有找到相关文章

最新更新