#php #doctrine #cascade
#php #доктрина #каскад
Вопрос:
Я хочу проверить свое понимание каскадных операций в ассоциациях Doctrine. Для целей этого вопроса у меня есть две модели: Customer
и Insuree
.
Если я определю отношение «многие ко многим» между Customer
и Insuree
и set cascade{"all"}
, я понимаю, что это будет:
- Добавление новой гарантии клиенту сохранит эту гарантию и создаст ассоциацию в таблице объединения.
- Удаление страхователя из коллекции отделит страхователя от клиента и отделит клиента от страхователя.
- Удаление клиента приведет к удалению всех страховщиков, связанных с клиентом.
Это определение ассоциации на 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;
Если я определю обратное отношение «многие ко многим» между Insuree
и Customer
и set cascade{"all"}
, я понимаю, что это будет:
- Добавление нового клиента к страхователю сохранит этого клиента и создаст ассоциацию в таблице объединения.
- Удаление клиента из коллекции приведет к отделению клиента от страхователя и отделению страхователя от клиента.
- Удаление страхователя приведет к удалению всех клиентов, связанных с ним.
Это определение ассоциации на Insurees
.
/**
* @ORMManyToMany(targetEntity="Customer", mappedBy="insurees", cascade={"all"})
*/
protected $customers;
Если я затем определю взаимосвязь для каскадирования при сохранении, слиянии и отсоединении — удаление страхователя не приведет к удалению всех связанных клиентов — это приведет только к удалению ассоциаций между страхователем и его клиентами?
/**
* @ORMManyToMany(targetEntity="Customer", mappedBy="insurees", cascade={"persist", "merge", "detach"})
*/
protected $customers;
Комментарии:
1. Разве вы не можете проверить, правильно ли вы понимаете каскадные отношения, создав некоторые
Customer
s иInsuree
s и начав удалять / добавлять записи?
Ответ №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()
фактически вернет новый управляемый объект, отдельный объект, который вы ему передали, остается неуправляемым.
Комментарии:
1. Следует отметить, что вызов
merge()
приведет к тому, что неуправляемая сущность перезапишет свойства управляемой сущности. Послеpersist()
теперь управляемый объект выполнит обновление таблицы этого объекта. Это может привести к неожиданной потере данных.