Доктрина 2.0 против 2.1 каскадное удаление OneToMany

#doctrine-orm

#доктрина-orm

Вопрос:

Здравствуйте, у меня возникла проблема при попытке каскадного удаления объектов в отношениях OneToMany. После нескольких часов отладки я попытался понизить версию doctrine с последней версии 2.1.2 до 2.0.2, и она внезапно начала работать.

Представьте две сущности Company и Address в отношении 1: N.

 /**
 * @Entity
 */
class Company extends Entity
{

 /**
  * @var integer
  * @id @Column(type="integer")
  * @generatedValue
  */
 private $id;

 /**
  * @var Collection
  * @OneToMany(targetEntity="Address",mappedBy="company", cascade={"persist","remove"})
  */
 private $addresses;
}



/**
 * @Entity
 */
class Address extends Entity
{

 /**
  * @var integer
  * @id @Column(type="integer")
  * @generatedValue
  */
 private $id;

 /**
  * @var Company
  * @ManyToOne(targetEntity="Company", inversedBy="addresses")
  * @JoinColumn(name="company_id", referencedColumnName="id",nullable=false)
  */
 private $company;
}
  

когда я пытаюсь удалить компанию-объект, я бы хотел, чтобы назначенные адреса также были удалены.

 $em->remove($company);
$em->flush();
  

В доктрине 2.1.2 удаление адресов не выполняется, поэтому ограничение целостности не выполняется. В версии 2.0.2 это работает отлично. Странная вещь, если я использую расширение EntityAudit https://github.com/simplethings/EntityAudit LogRevisionListener корректно управляет версиями объектов addresses (устанавливает для них revtype = DEL) в doctrine 2.1.2 (конечно, и в 2.0.2), но UnitOfWork не удаляет его.

Есть ли какая-либо разница в том, как обрабатывать каскадное удаление в 2.0.2 и в 2.1.2?

Большое вам спасибо

Комментарии:

1. Я тоже наткнулся на эту проблему сегодня, я использую 2.1.6. :/

2. Ну, я должен исправить себя, теперь это работает для меня! Я использовал cascade={"all"} , но когда я изменил его, cascade={"remove"} все начало работать просто отлично.

3. Хотя я должен сказать, что, вероятно, моя проблема может быть не полностью связана с набором аннотаций или самой Doctrine, потому что я выполняю интенсивные манипуляции с объектами, и после некоторого тестирования комбинации каскадных опций я обнаружил, что именно этот "merge" вариант вызывает проблемы. Надеюсь, это все равно поможет 🙂

Ответ №1:

Попробуйте использовать это для addresses атрибута вашего Company класса

 @OneToMany(targetEntity="Address",mappedBy="company", 
cascade={"persist"}, orphanRemoval=true)
  

Комментарии:

1. Я использую доктрину 2.2.3 и все тот же. Пришлось добавить orphanRemoval=true . Немного странно, потому что я не удаляю одну сторону, поэтому не создаю сирот. Может быть, потому, что сторона многих является стороной-владельцем, и я удаляю с одной стороны. Обновления работают, потому что многие стороны являются владельцами, и я использую $this->addSomething(theThing) и theThing->setSomething($this) где, как если бы я удалял что-то, ничего не настраивается, только $this->removeSomething(theThing)

Ответ №2:

У меня была та же проблема… Отношения были добавлены или обновлены, но не удалены, даже если у меня был cascade: [persist, remove] .

Я обнаружил, что мне не нужен атрибут «удалить» в «каскаде», но мне пришлось добавить orphanRemoval: true.

Я сходил с ума, ты сделал мой день!

Ответ №3:

Я столкнулся с той же проблемой и решил ее с помощью этого кода :

 $em->remove($object);
$em->flush();
$em->remove($user);
$em->flush();
  

Может быть, вы можете использовать a findAll для своих company адресов и удалить это с foreach помощью такого :

 // Return all the addresses of the company
$addresses = $em->getRepository(...)->findAllAddressesByCompany($company);
$em->remove($company);
foreach ($address in $addresses)
{
    $em->remove($address);
}
  

Это не очень хороший метод, но на данный момент это все, что я нашел.

Комментарии:

1. Я решил это, понизив рейтинг doctrine 🙂 спасибо, но это не тот метод, который я ищу: (вероятно, это может быть ошибка (или особенность?)