了解学说级联操作

2022-01-16 00:00:00 php doctrine cascade

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

I want to check my understanding of cascade operations on Doctrine associations. For the purpose of this question, I have two models: Customer and Insuree.

如果我定义 CustomerInsuree 之间的多对多关系并设置 cascade{"all"},我明白这将:

If I define a many to many relationship between a Customer and Insuree and set cascade{"all"}, I understand that this will:

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

这是Customers上关联的定义.

/**
 * @ORMManyToMany(targetEntity="Insuree", inversedBy="customers", cascade={"all"})
 * @ORMJoinTable(name="customer_insuree",
 *      joinColumns={@ORMJoinColumn(name="customer_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORMJoinColumn(name="insuree_id", referencedColumnName="id")}
 * )
 */
protected $insurees;

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

If I define the inverse many to many relationship between an Insuree and Customer and set cascade{"all"}, I understand that this will:

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

这是Insurees上关联的定义.

/**
 * @ORMManyToMany(targetEntity="Customer", mappedBy="insurees", cascade={"all"})
 */
protected $customers;

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

If I then define the relationship as to cascade on persist, merge and detach - deleting the insuree will not delete all associated customers - it will only remove the associations between the insuree and its customers?

/**
 * @ORMManyToMany(targetEntity="Customer", mappedBy="insurees", cascade={"persist", "merge", "detach"})
 */
protected $customers;

推荐答案

persist &删除

您对 cascade={"persist"} 的理解是正确的,这意味着持久化实体 A,Doctrine 也将持久化集合中的所有 B 实体.

You are correct about cascade={"persist"} meaning that persisting entity A, Doctrine will also persist all B entities in the Collection.

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

You are also correct about cascade={"remove"} meaning that removing entity A, Doctrine will also remove all B entities in the Collection.
But I doubt you would ever want to use this on a ManyToMany association, because when you remove entity A that cascades this operation to all B entities, those B entities might be associated to other A entities.

分离 &合并

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

You are not correct about cascade={"detach"} and cascade={"merge"}:

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

Adding/removing entities from the Collection is something you need to do (in your code). Read about that here.

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

Detach means that you detach an entity from the EntityManager. The EntityManager will no longer manage that entity. This makes a detached entity the same as a newly instantiated entity, except that it's already in the database (but you made the EntityManager unaware of that).

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

In other words: cascade={"detach"} means that detaching entity A, Doctrine will also detach all B entities in the Collection.

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

Merge is the opposite of detach: You will merge a detached entity back into the EntityManager.
Do note that merge() will actually return a new managed object, the detached object you passed to it remains unmanaged.

相关文章