删除关联/引用的实体

时间:2013-03-27 09:00:41

标签: doctrine-orm

我有一个表产品,这些表中的项目在 cart_item order_item 等表格中引用,以及 shipping_item 等。

所有这些引用都是可选的(product_id在这些表中设置为可为空)。

我需要有办法删除产品并保留其他表的记录。我能想到的一种方法是进入所有这些表,将product_id设置为null,然后返回产品表进行删除。但是,由于我可能不知道引用产品的所有表(许多其他捆绑包可以包含引用此产品的实体),是否有一种方法可以让我知道所有这些关联到循环通过并设置null?

(或许有更好的方法?)

PS:认为这是一个购物车,并且所有者可能想要删除过期的产品以进行清理,但对于订购的,仍然需要保存记录的已装运物品。

EDIT1:

这是OrderItem实体中产品引用的定义:

/**
 * @var \Product
 *
 * @ORM\ManyToOne(targetEntity="Product")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="product_id", referencedColumnName="id")
 * })
 */
private $product;

我得到的错误:

  

PDOException:SQLSTATE [23000]:完整性约束违规:1451   无法删除或更新父行:外键约束失败   (testorder_item,C ONSTRAINT fk_order_item_product1外键   (product_id)引用productid)ON DELETE NO ACTION ON   更新无行动)

EDIT2:

我最初将onupdate =“SET NULL”设置为order_item实体并认为这已经足够了,它不是:

/**
 * @var \Product
 *
 * @ORM\ManyToOne(targetEntity="Product")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="product_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
 * })
 */
private $product;

之后,我还必须更新数据库模式。

1 个答案:

答案 0 :(得分:3)

假设您在拥有实体product与其他实体之间建立了正确的关系,例如cart_item应该有一个foreign_key,你想要的行为是doctrine 2的默认行为。

manual

中查看此处

作为示例,他们会显示删除User实体及其对应的Comments

$user = $em->find('User', $deleteUserId);

foreach ($user->getAuthoredComments() AS $comment) {
    $em->remove($comment);
}
$em->remove($user);
$em->flush();

示例说明:

  

没有循环遍历所有创作的注释,Doctrine只会使用UPDATE语句将外键设置为NULL,并且在flush() - Operation期间只会从数据库中删除User。

这告诉我,在您的情况下,您实际上想要这种行为。因此,只需删除product实体,并且doctrine 2将自动查找具有属于该产品的foreign_key的所有其他实体,并将其设置为NULL

修改
您的错误消息表明,在尝试删除product实体时,仍然存在foreign_keys,即Doctrine尚未将它们正确设置为null。 您需要确保将cascade属性,特别是remove添加到您的实体关系中。它看起来像下面这样:

<?php
class Product
{
    //...
    /**
     * Bidirectional - One-To-Many (INVERSE SIDE)
     *
     * @OneToMany(targetEntity="Cart", mappedBy="product", cascade={"remove"})
     */
    private $carts;
    //...
}