Doctrine2 - 无法删除具有单向 oneToMany 关系的实体

Posted

技术标签:

【中文标题】Doctrine2 - 无法删除具有单向 oneToMany 关系的实体【英文标题】:Doctrine2 - Cannot delete an entity with a unidirectional oneToMany relation 【发布时间】:2013-05-22 18:31:22 【问题描述】:

我在尝试删除包含单向一对多关联的实体时遇到外部约束违规。我有以下简单的类:

class Dealer

/**
 * @ManyToMany(targetEntity="Car", cascade="persist", "remove")
 * @JoinTable(name="dealer_cars",
 *      joinColumns=@JoinColumn(name="dealer_id", referencedColumnName="id"),
 *      inverseJoinColumns=@JoinColumn(name="car_id", referencedColumnName="id",
        unique=true)
 *    )
 **/
  protected cars;

在这种情况下,Car 对象不应包含与其所有者的关系(因此是单向关系)。如果我尝试删除包含与汽车的关联的 Dealer 对象,则会出现以下约束违规:

Cannot delete or update a parent row: a foreign key constraint fails 
(`application`.`dealer_cars`, CONSTRAINT `FK_E1BCEEEBC3C6F69F`
 FOREIGN KEY (`car_id`) REFERENCES `car` (`id`))'

如果我尝试从数据库表中手动删除经销商行,我会收到相同的消息,但我认为使用 cascade="remove" 的 Doctrine 会为我解决这个问题。

如果我将关联更改为双向关联,它会起作用。为什么这不适用于单向关联?

【问题讨论】:

单向一对多关联 ?这对我来说更像是双向多对多:D 当您更改架构时,您是否删除了数据库并重新创建,或者您在数据库中有任何固定装置/数据剩余物? 你想在不丢失汽车的情况下删除经销商,我说对了吗? 是Doctrine对单向一对多的定义。它是具有唯一约束的多对多。我想删除汽车,同时删除经销商。 但是我发现了问题。我需要在外键表的 car_id 列中添加一个onDelete="cascade" 属性。这显然是有道理的!感谢您的关注:) 【参考方案1】:

在 Doctrine 中使用数据库级别的 onDelete 选项

@ORM\JoinColumn(name="dealer_id", referencedColumnName="id",  onDelete="SET NULL")

来自here的解释:

CASCADE 将在父项更改时传播更改。 (如果您删除了一行,则约束表中引用该行的行也将被删除,等等)

当父行消失时,SET NULL 将列值设置为 NULL。

RESTRICT 导致尝试删除父行失败。


...更新您的数据库架构,然后再抱怨它不工作:-)

app/console doctrine:schema:update --force

如果由于外键错误而无法正常工作(按此顺序):

应用程序/控制台原则:数据库:drop 应用程序/控制台原则:数据库:创建 app/console 原则:schema:update --force (可选:应用程序/控制台原则:fixtures:load)

【讨论】:

是的,就是这样。我猜“SET NULL”的效果和“级联”一样好。

以上是关于Doctrine2 - 无法删除具有单向 oneToMany 关系的实体的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 项目中的 Doctrine2 映射问题

在 Doctrine2 上找不到实体异常

在Doctrine2上找不到实体

Doctrine 2 不能在 manyToOne 关系中使用 nullable=false?

Doctrine2.3 和 OneToOne 级联持续似乎不起作用

Doctrine2 刷新单个删除的实体