Doctrine orm 删除关联/引用的实体
我有一个表产品,这些表中的项目在表中引用,例如购物车项目和订单项目以及装运项目等 所有这些引用都是可选的(在这些表中,product_id设置为null) 我需要有一种方法来删除一个产品,同时保留其他表的记录。我能想到的一种方法是进入所有这些表,将product_id设置为null,然后返回要删除的product表。但是,由于我可能不知道引用产品的所有表(许多其他捆绑包可能有引用此产品的实体),有没有办法知道所有这些关联以循环并设置为空 (或者有更好的方法?) 附言:这是一个购物车的想法,车主可能想移除过期的产品进行清理,但对于订购的、已发货的商品,他们仍然需要保留记录 Edit1: 这是OrderItem实体中产品引用的定义:Doctrine orm 删除关联/引用的实体,doctrine-orm,Doctrine Orm,我有一个表产品,这些表中的项目在表中引用,例如购物车项目和订单项目以及装运项目等 所有这些引用都是可选的(在这些表中,product_id设置为null) 我需要有一种方法来删除一个产品,同时保留其他表的记录。我能想到的一种方法是进入所有这些表,将product_id设置为null,然后返回要删除的product表。但是,由于我可能不知道引用产品的所有表(许多其他捆绑包可能有引用此产品的实体),有没有办法知道所有这些关联以循环并设置为空 (或者有更好的方法?) 附言:这是一个购物车的想法,车主可
/**
* @var \Product
*
* @ORM\ManyToOne(targetEntity="Product")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
* })
*/
private $product;
我得到的错误是:
PDOException:SQLSTATE[23000]:完整性约束冲突:1451
无法删除或更新父行:外键约束失败
(test
order\u item
,C ONSTRAINTfk\u order\u item\u product1
外键
(product\u id
)在删除时参考product
(id
)在删除时不执行任何操作
更新(无操作)
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;
在那之后,我还必须更新db模式。假设您在拥有的实体
产品
和其他实体之间建立了适当的关系,例如应该有外键的购物车项目
,您想要的行为是原则2的默认行为
请看下面的图片
例如,它们显示了删除用户
实体及其相应的注释
$user = $em->find('User', $deleteUserId);
foreach ($user->getAuthoredComments() AS $comment) {
$em->remove($comment);
}
$em->remove($user);
$em->flush();
该示例说明:
如果没有对所有编写的注释进行循环,则在flush()操作期间,条令将仅使用UPDATE语句将外键设置为NULL,并且仅从数据库中删除用户
这向我表明,在你的情况下,你实际上想要这种行为。因此,只需删除产品
实体,原则2将自动找到所有其他实体,其外键属于该产品,并将其设置为空
编辑您的错误消息表明,在尝试删除
产品
实体时,仍存在外键,即未根据原则将其正确设置为null。
您需要确保将级联
属性,特别是删除
添加到实体关系中。它看起来类似于以下内容:
<?php
class Product
{
//...
/**
* Bidirectional - One-To-Many (INVERSE SIDE)
*
* @OneToMany(targetEntity="Cart", mappedBy="product", cascade={"remove"})
*/
private $carts;
//...
}
Hi Pankrates,谢谢你指出这一点,这似乎就是教义文件所说的。我已经用实体def更新了我的问题和我得到的错误,你能看看我是否犯了任何错误吗?非常感谢,我不想在cascade上删除它,但你的回答实际上引导了我正确的方向。看起来我也必须在数据库中将触发器设置为onupdatesetnull,我最初只在实体中设置了它,并且认为这已经足够了