2015-04-18 4 views
7

Предположим, что у нас есть два объекта (Profile и Address). Профиль может иметь много адресов. В этом случае мы имеем:Does orphanRemoval bypass onDelete?

Profile: 
    ... 
    fields: 
     ... 
    oneToMany: 
     addresses: 
      targetEntity: Address 
      mappedBy: profile 
      orphanRemoval: true 

Address: 
    ... 
    fields: 
     ... 
    manyToOne: 
     profile: 
      targetEntity: Profile 
      inversedBy: addresses 
      joinColumn: 
       name: profile_id 
       referencedColumnName: id 
       onDelete: cascade 

Теперь, если удалить профиль, который имеет много адресов:

$em->remove($profile); 

Как адреса удаляются?

Doctrine извлекает все адреса, относящиеся к этому профилю, а затем удаляет их или удаляет только профиль и позволяет базе данных обрабатывать адреса?

Я нашел несколько ответов относительно Hibernate, но ничего о Доктрина.


EDIT: Добавить три записки от Доктрины книги

1.Ел ассоциацию помечаются как CASCADE = REMOVE Doctrine 2 загрузит эту ассоциацию. Если его единая ассоциация передаст этот объект EntityManager#remove(). Если ассоциация представляет собой коллекцию, Doctrine будет перебирать все ее элементы и передавать их в EntityManager#remove(). В обоих случаях семантика удаления каскада применяется рекурсивно. Для графов больших объектов эта стратегия удаления может быть очень дорогостоящей.

2. Использование оператора DQL DELETE позволяет удалить несколько объектов типа с помощью одной команды и без увлажнения этих объектов. Это может быть очень эффективным для удаления графов больших объектов из базы данных.

3. Использование семантики внешнего ключа onDelete = «CASCADE» может заставить базу данных удалить все связанные объекты внутри. Эта стратегия немного сложна, чтобы получить право, но может быть очень мощной и быстрой. Вы должны знать, что использование стратегии 1 (CASCADE=REMOVE) полностью обходит любой внешний ключ onDelete=CASCADE вариант, поскольку Doctrine будет получать и удалять все связанные объекты явно.

ответ

3

Я тест:

Я первый принести Profile (только profile без присоединиться) и передать его в $em->remove($profile), то доктрины запустить другой запрос, извлекающий все Address, которые связаны с Profile (один запросом) и после него доктрина запускает запрос на удаление для каждого адреса, который связан с Profile, а в финале удаляет Profile.

так, я могу сказать, что orphanRemoval другого типа каскадных, как говорит доктрина:

orphanRemoval: Существует еще одна концепции каскадирования, которая имеет отношение только при удалении сущностей из коллекций

и orphanRemoval обход onDelete.

1

В руководстве по доктрине есть раздел о orphan removal. Существует также another question уточнение onDelete: cascade. Надеюсь, эти две ссылки помогут вам понять эту тему.

Кроме того, убедитесь, что после $em->remove($profile); вы вызываете операцию $em->flush(); для синхронизации локальной единицы работы с базой данных.

+0

спасибо за ваш ответ, я прочитал эти документы, но я не могу найти ответ – ghanbari

+0

Итак, если я сейчас правильно понимаю ваш вопрос, вам интересно, как Doctrine внутренне создает команду DELETE SQL? –

+0

Нет, мой вопрос заключается в следующем: когда я удаляю профиль, как удаляются addreses? by databse ('onDelete') или доктрина (' orphanRemovel = true') – ghanbari