了解学说级联操作

Posted

技术标签:

【中文标题】了解学说级联操作【英文标题】:Understanding Doctrine Cascade Operations 【发布时间】:2014-08-28 01:23:14 【问题描述】:

我想检查我对 Doctrine 关联的级联操作的理解。对于这个问题,我有两个模型:CustomerInsuree

如果我在CustomerInsuree 之间定义多对多关系并设置cascade"all",我知道这将:

向客户添加新的被保险人将保留该被保险人并在连接表中创建关联。 从集合中删除被保险人将使被保险人与客户分离,并将客户与被保险人分离。 删除客户将删除与该客户关联的所有被保险人。

这是Customers上的关联定义。

/**
 * @ORM\ManyToMany(targetEntity="Insuree", inversedBy="customers", cascade="all")
 * @ORM\JoinTable(name="customer_insuree",
 *      joinColumns=@ORM\JoinColumn(name="customer_id", referencedColumnName="id"),
 *      inverseJoinColumns=@ORM\JoinColumn(name="insuree_id", referencedColumnName="id")
 * )
 */
protected $insurees;

如果我定义 InsureeCustomer 之间的反向多对多关系并设置 cascade"all",我知道这将:

向被保险人添加新客户将保留该客户并在连接表中创建关联。 从集合中删除客户将使客户与被保险人分离,并将被保险人与客户分离。 删除被保险人将删除与其关联的所有客户。

这是Insurees上的关联定义。

/**
 * @ORM\ManyToMany(targetEntity="Customer", mappedBy="insurees", cascade="all")
 */
protected $customers;

如果我随后将关系定义为在持久化、合并和分离上级联 - 删除被保险人不会删除所有关联的客户 - 它只会删除被保险人与其客户之间的关联?

/**
 * @ORM\ManyToMany(targetEntity="Customer", mappedBy="insurees", cascade="persist", "merge", "detach")
 */
protected $customers;

【问题讨论】:

您不能通过创建一些Customers 和Insurees 并开始删除/添加记录来检查您对级联关系的理解是否正确吗? 【参考方案1】:

保留并删除

cascade="persist" 是正确的,这意味着持久化实体 A,Doctrine 也将持久化集合中的所有 B 实体。

您对cascade="remove" 也是正确的,这意味着删除实体 A,Doctrine 也将删除集合中的所有 B 实体。 但我怀疑您是否希望在多对多关联上使用它,因为当您删除将此操作级联到所有 B 实体的实体 A 时,这些 B 实体可能会与其他 A 实体相关联。

分离和合并

关于cascade="detach"cascade="merge",您不正确

从集合中添加/删除实体是需要做的事情(在您的代码中)。阅读here。

Detach 表示您从 EntityManager 中分离实体。 EntityManager 将不再管理该实体。这使得分离的实体与新实例化的实体相同,只是它已经在数据库中(但您让 EntityManager 不知道这一点)。

换句话说:cascade="detach" 表示分离实体 A,Doctrine 也会分离 Collection 中的所有 B 实体。

Mergedetach 是相反的:您将分离的实体合并回 EntityManager。 请注意,merge() 实际上会返回一个 new 托管对象,而您传递给它的分离对象仍然是非托管对象。

【讨论】:

需要注意的是,调用merge()会导致非托管实体覆盖托管实体的属性。在persist() 时,现在管理的实体将针对该实体的表执行更新。这可能会导致意外的数据丢失。

以上是关于了解学说级联操作的主要内容,如果未能解决你的问题,请参考以下文章

ORM(学说)和SQL之间的代码比较?

学说部分对象......是为了表现吗?

了解 MVC 中的 ORM 模型

Hibernate @OneToOne 单向映射...级联删除

Java使用c3p0连接池完成多表级联查询

训练级联分类器,同时包括图像注释作为特征