理解Doctrine级联操作

86

我想确认一下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;
如果我在一个Insuree和Customer之间定义了多对多的反向关系,并设置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;

1
你不能通过创建一些“客户”和“被保险人”并开始删除/添加记录来检查你对级联关系的理解是否正确吗? - undefined
1个回答

177

持久化 & 删除

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

关于cascade={"remove"}你也是正确的,这意味着删除实体A时,Doctrine也将删除集合中的所有B实体。
但我怀疑您永远不会想在ManyToMany关联上使用它,因为当你删除级联到所有B实体的实体A时,这些B实体可能与其他A实体相关联。

分离 & 合并

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

向/从集合中添加/删除实体是需要做的(在您的代码中)。请在这里了解更多信息。

分离指的是将实体从EntityManager中分离。 EntityManager将不再管理该实体。这将使一个分离的实体与新实例化的实体相同,除了它已经存在于数据库中(但你让EntityManager不知道)。

换句话说:cascade={"detach"}意味着将实体A分离,Doctrine也将分离集合中的所有B实体。

合并分离的相反操作:您将会把一个分离的实体合并回到EntityManager中。
请注意,merge()实际上会返回一个新的托管对象,您传递给它的分离对象仍然没有被管理。


4
需要注意的是,调用merge()方法将会导致非托管实体覆盖托管实体的属性。在调用persist()方法后,现在的托管实体会对该实体所在的表格执行更新操作。这可能会导致意外的数据丢失。 - Kevin Mesiab

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接