Я пытаюсь сделать простой пример, чтобы узнать, как удалить строку из родительской таблицы и автоматически удалить совпадающие строки в дочерней таблице с помощью Doctrine2.
Вот две сущности, которые я использую:
Child.php:
<?php
namespace Acme\CascadeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="child")
*/
class Child {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToOne(targetEntity="Father", cascade={"remove"})
*
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="father_id", referencedColumnName="id")
* })
*
* @var father
*/
private $father;
}
Father.php
<?php
namespace Acme\CascadeBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="father")
*/
class Father
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
}
Таблицы правильно созданы в базе данных, но опция «Удалить каскад» не создается. Что я делаю не так?
php
doctrine-orm
symfony
cascading-deletes
rfc1484
источник
источник
Ответы:
В Учении есть два вида каскадов:
1) Уровень ORM - используется
cascade={"remove"}
в ассоциации - это расчет, который выполняется в UnitOfWork и не влияет на структуру базы данных. Когда вы удаляете объект, UnitOfWork будет перебирать все объекты в ассоциации и удалять их.2) Уровень базы данных - используется
onDelete="CASCADE"
для joinColumn ассоциации - это добавит Каскад при удалении к столбцу внешнего ключа в базе данных:Я также хочу отметить, что если у вас сейчас есть ваш каскад = {"remove"}, то при удалении дочернего объекта этот каскад удалит родительский объект. Понятно не то, что вы хотите.
источник
onDelete
так же какcascade = {"remove"}
, например , когда у вас есть какой - то объект , связанный с fosUser. Оба объекта не должны существовать в одиночку@ORM\JoinColumn(onDelete="CASCADE")
и все же позволить доктрине автоматически обрабатывать имена столбцов.onDelete="CASCADE"
не будет иметь никакого эффекта, так как Doctrinecascade={"remove"}
удаляет связанные сущности перед удалением корневой сущности (это необходимо). Таким образом, когда корневая сущность удаляется, не остается никаких внешних связей дляonDelete="CASCADE"
удаления. Но чтобы быть уверенным, я бы предложил вам создать небольшой тестовый пример и посмотреть на выполняемые запросы и порядок их выполнения.Вот простой пример. У контакта есть один-много связанных телефонных номеров. Когда контакт удален, я хочу, чтобы все связанные с ним номера телефонов также были удалены, поэтому я использую ON DELETE CASCADE. Отношение «один ко многим / многие к одному» реализуется с помощью внешнего ключа в phone_numbers.
При добавлении «ON DELETE CASCADE» к ограничению внешнего ключа номера телефона будут автоматически удаляться при удалении связанного с ними контакта.
Теперь, когда строка в таблице контактов удалена, все связанные с ней строки phone_numbers будут автоматически удалены.
Чтобы добиться того же в Doctrine, чтобы получить тот же уровень поведения «ON DELETE CASCADE» на уровне базы данных, вы конфигурируете @JoinColumn с параметром onDelete = "CASCADE" .
Если вы сейчас делаете
вы увидите, что будет сгенерирован тот же SQL, что и в первом примере с raw-SQL
источник
onDelete="cascade"
правильно помещается в сущность (на дочернем объекте), потому что это SQL-каскад , который размещается на дочернем объекте . Только каскад Доктрины (cascade=["remove"]
который здесь не используется) помещается на родительский элемент.