【问题标题】:Does orphanRemoval bypass onDelete?orphanRemoval 是否绕过 onDelete?
【发布时间】:2015-06-25 17:05:17
【问题描述】:

假设我们有两个实体(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 的答案,但没有找到关于 Doctrine 的答案。


EDIT:添加 Doctrine

中的三个注释

1.如果关联被标记为 CASCADE=REMOVE,则 Doctrine 2 将获取此关联。如果它是一个单一关联,它将把这个实体传递给EntityManager#remove()。如果关联是一个集合,Doctrine 将遍历它的所有元素并将它们传递给EntityManager#remove()。在这两种情况下,级联删除语义都是递归应用的。对于大型对象图,这种删除策略可能非常昂贵。

2.使用 DQL DELETE 语句,您可以使用单个命令删除一个类型的多个实体,而无需对这些实体进行水合。这对于从数据库中删除大型对象图非常有效。

3.使用外键语义 onDelete="CASCADE" 可以强制数据库在内部删除所有关联对象。这种策略要正确有点棘手,但可以非常强大和快速。 但是您应该知道,使用策略 1 (CASCADE=REMOVE) 会完全绕过任何外键 onDelete=CASCADE 选项,因为 Doctrine 仍会显式获取并删除所有关联实体。

【问题讨论】:

    标签: php symfony doctrine-orm doctrine


    【解决方案1】:

    我做一个测试:

    我首先获取Profile(只有profile 没有join)并将其传递给$em->remove($profile),然后doctrine 运行另一个查询来获取所有@987654324 @ 与Profile 相关的@(一个查询),在它之后,doctrine 对与Profile 相关的每个地址运行一个删除查询,最后它删除Profile

    所以,我可以说 orphanRemoval 是另一种级联,正如教义所说:

    orphanRemoval:还有另一个级联概念,仅在从集合中删除实体时才相关

    orphanRemoval绕过onDelete

    【讨论】:

      【解决方案2】:

      Doctrine 手册中有一个关于orphan removal 的部分。还有another question 澄清onDelete: cascade。我希望这两个链接可以帮助您进一步了解该主题。

      另外,请确保在 $em->remove($profile); 之后调用 $em->flush(); 操作以将本地工作单元同步到数据库。

      【讨论】:

      • 感谢您的回答,我阅读了这些文件,但找不到答案
      • 那么,如果我现在正确理解了您的问题,您想知道 Doctrine 如何在内部创建 DELETE SQL 命令?
      • 不,我的问题是:当我删除个人资料时,如何删除地址?通过数据库(onDelete)或学说(orphanRemovel=true
      • 是的,这些基本上是您拥有的选项。如果你对详细发生的事情感兴趣,你可以实现一个profiler并分析不同选项执行的SQL。
      猜你喜欢
      • 2015-02-12
      • 2018-03-07
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 1970-01-01
      相关资源
      最近更新 更多