Понимание каскадных операций Doctrine

Я хочу проверить свое понимание каскадных операций над ассоциациями Doctrine. Для этого вопроса у меня есть две модели: Customer и Insuree.

Если я определяю отношение "многие-многие" между Customer и Insuree и устанавливаю 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;

Если я затем определяю отношение к каскаду на persist, слияние и отключение - удаление инсайдера не удалит всех связанных с ним клиентов - он удалит ассоциации между страхователем и его клиентами?

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

Ответ 1

сохранить и удалить

Вы правы в отношении cascade={"persist"}, что означает, что сохраняющаяся сущность A, Doctrine также будет сохраняться все B-объекты в коллекции.

Вы также верны в отношении cascade={"remove"}, что означает, что удаление объекта A, Doctrine также удалит все элементы B в коллекции.
Но я сомневаюсь, что вы когда-нибудь захотите использовать это в ассоциации ManyToMany, потому что когда вы удаляете объект A, который каскадирует эту операцию ко всем объектам B, эти объекты B могут быть связаны с другими объектами A.

отсоединить и слить

Вы не уверены в cascade={"detach"} и cascade={"merge"}:

Добавление/удаление объектов из коллекции - это то, что вам нужно сделать (в вашем коде). Читайте об этом здесь.

Отсоединение означает, что вы отсоединяете объект от EntityManager. EntityManager больше не будет управлять этим объектом. Это делает отдельный объект тем же, что и вновь созданный объект, за исключением того, что он уже находится в базе данных (но вы не осознали этого EntityManager).

Другими словами: cascade={"detach"} означает, что отсоединение объекта A, Doctrine также отделяет все объекты B в коллекции.

Объединить противоположность отделить: вы объедините отдельный объект обратно в EntityManager.
Обратите внимание, что merge() фактически вернет новый управляемый объект, удаленный объект, который вы ему передали, остается неуправляемым.