Подтвердить что ты не робот

Глубокий клонированный объект Doctrine с связанными объектами

Я создал объект A с отношением OneToMany к B, которые имеют отношение OneToMany к C.

Мне нужно клонировать этот объект A и устанавливать его в базе данных с новым идентификатором. Кроме того, все глубокие отношения должны быть клонированы также с новыми идентификаторами.

Что я пытался установить A id на null:

$A = clone $A_original;
$A->setId(null);
$em->persist($A);

Он создает новую запись в таблице A, но не находится в B и C.

Что делать, чтобы сделать полную копию объекта A?

4b9b3361

Ответ 1

Вы должны внедрить метод __clone() в своих сущностях, который устанавливает id в значение null и при необходимости связывает отношения. Поскольку, если вы сохраняете идентификатор в связанном объекте, предполагается, что ваш новый объект A имеет отношение к существующим объектам B и C.

Клонный метод для A:

public function __clone() {
    if ($this->id) {
        $this->setId(null);
        $this->B = clone $this->B;
        $this->C = clone $this->C;
    }
}

Клон-метод для B и C:

public function __clone() {
    if ($this->id) {
        $this->setId(null);
    }
}

https://groups.google.com/forum/?fromgroups=#!topic/doctrine-user/Nu2rayrDkgQ

https://doctrine-orm.readthedocs.org/en/latest/cookbook/implementing-wakeup-or-clone.html

На основе комментария coder4show клон-метод отношения OneToMany на A, где $this->M является OneToMany и, следовательно, ArrayCollection:

public function __clone() {
    if ($this->id) {
        $this->setId(null);

        // cloning the relation M which is a OneToMany
        $mClone = new ArrayCollection();
        foreach ($this->M as $item) {
            $itemClone = clone $item;
            $itemClone->setA($this);
            $mClone->add($itemClone);
        }
        $this->M = $mClone;
    }
}

Ответ 2

Существует также модуль, который будет делать это под названием DeepCopy:

https://github.com/myclabs/DeepCopy

$deepCopy = new DeepCopy();
$myCopy   = $deepCopy->copy($myObject);

Вы также можете добавить фильтры для настройки процесса копирования.