ORM Doctrine ManyToOne on update CASCADE (Symfony)

Posted

技术标签:

【中文标题】ORM Doctrine ManyToOne on update CASCADE (Symfony)【英文标题】: 【发布时间】:2013-04-24 19:55:36 【问题描述】:

我有两个实体

class Promotor


/**
 * @ORM\ManyToOne(targetEntity="Ciudad", inversedBy="promotor")
 * @ORM\JoinColumn(name="ciudad_id", referencedColumnName="id", nullable=false)
 */
protected $ciudad;

class Ciudad

/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="nombre", type="string", length=50)
 */
private $nombre;

“发起人”可以住在一个“Ciudad”(城市)中。而在一个“Ciudad”(城市)中可以住很多“Promotores”。

如果我在 JoinColumn 中添加 onDelete="CASCADE"

/**
 * @ORM\ManyToOne(targetEntity="Ciudad", inversedBy="promotor")
 * @ORM\JoinColumn(name="ciudad_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
 */
protected $ciudad;

它生成下一个代码

ALTER TABLE promotor DROP FOREIGN KEY FK_BF20A37FE8608214;
ALTER TABLE promotor ADD CONSTRAINT FK_BF20A37FE8608214 FOREIGN KEY (ciudad_id)
REFERENCES Ciudad (id) ON DELETE CASCADE

但我也喜欢在更新时做 CASCADE。我尝试使用 onUpdate="CASCADE" 但它不起作用

[Doctrine\Common\Annotations\AnnotationException]
[Creation Error] The annotation @ORM\JoinColumn declared on property     Web\PromotorBundle\Entity\Promotor::$ciudad does not have a property named
"onUpdate". Available properties: name, referencedColumnName, unique, nulla
ble, onDelete, columnDefinition, fieldName

根据错误,我知道属性 onUpdate 不存在,但是.. 有没有办法在更新时进行级联?

【问题讨论】:

我在学说的文档中找到了这个注释,但我不明白。不再需要在更新时控制级联。理论上它永远不会改变 id doctrine-project.org/jira/browse/… 【参考方案1】:

onDelete="CASCADE" 用于数据库级别。正如你已经说过的,没有 onUpdate。另一个缺点是 ON DELETE CASCADE 仅适用于 InnoDB。它不适用于 MyISAM。

但是你可以使用 Doctrine 内存级联操作:

class Promotor


/**
* @ORM\ManyToOne(targetEntity="Ciudad", inversedBy="promotor", cascade="persist", "remove")
* @ORM\JoinColumn(name="ciudad_id", referencedColumnName="id", nullable=false)
*/
protected $ciudad;

文档中都有描述:https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html#transitive-persistence-cascade-operations

另外,您可以跳过 JoinColumn 注释,因为您编写它的方式是默认配置,并且它是隐式生成的。

所以你可以写:

class Promotor


/**
* @ORM\ManyToOne(targetEntity="Ciudad", inversedBy="promotor", cascade="persist", "remove")
*/
protected $ciudad;

【讨论】:

顺便说一句,如果Ciudad 实体没有字段$promotor$ciudad 属性上怎么会有inversedBy="promotor"? (甚至从 MTO 关系的性质来看,它根本不能“反向”引用 Promotor)? 你是对的,Ciudad 实体上没有 promotor 属性。所以不可能有inversedBy="promotor"。但是您对 ManyToOne 关系和 inverse 参考是错误的。 ManyToOne 有inverse,OneToMany 有mappedBy 抱歉,我的措辞不够准确。当我说“逆”时,我实际上是指相同的inversedBy。此外,尽管您所说的似乎合乎逻辑(不可能有inversedBy="promotor"),但我查找了@ManyToOne doctrine-orm.readthedocs.org/en/latest/reference/… 的文档,它提到了这个inversedBy 参数(尽管不是强制性的)。但我仍然很困惑——MTO 关系怎么可能有inversedBy?这不是真的吗,可能有inversedBy 是ManyToMany 关系吗? 我想我明白了:根据文档The inversedBy attribute designates the field in the entity that is the inverse side of the relationship. 关键字是field in the entity - 它是其他实体中的一个字段(但在数据库中的其他实体表示中将不会为该关系添加的额外字段)。它仍然是 MTO 到 OTM 的关系。

以上是关于ORM Doctrine ManyToOne on update CASCADE (Symfony)的主要内容,如果未能解决你的问题,请参考以下文章

Doctrine ORM ManyToOne Inverse 不起作用

使用 Doctrine ORM ManyToOne 关系在相反方向获取实体

Doctrine ManyToOne 关系 - 在“设置”时自动删除

Doctrine ORM Association映射两列

禁用 Doctrine 外键约束

Symfony 5(Doctrine 2.9),Doctrine 不会为 ManyToOne 自引用关系生成迁移