web-dev-qa-db-fra.com

Entité Doctrine clonée profonde avec entités apparentées

J'ai créé une entité A avec OneToMany relation à B, avec laquelle relation OneToMany à C.

Je dois cloner cette entité A et la définir dans la base de données avec le nouvel identifiant. De plus, toutes les relations profondes doivent également être clonées avec de nouveaux identifiants.

Qu'est-ce que j'ai essayé, c'est de définir A id sur null:

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

Il crée un nouvel enregistrement dans la table A, mais pas dans les B et C.

Que dois-je faire pour créer une copie complète de l'entité A?

36
hsz

Vous devez implémenter une méthode __clone() dans vos entités qui définit l'id sur null et clone les relations si vous le souhaitez. Parce que si vous conservez l'identifiant dans l'objet associé, cela suppose que votre nouvelle entité A a une relation avec les entités existantes B et C.

Méthode de clonage pour A:

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

Méthode de clonage pour B et 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/fr/latest/cookbook/implementing-wakeup-or-clone.html

D'après le commentaire de coder4show, une méthode de clonage pour une relation OneToMany sur A, où $this->M est OneToMany et donc une 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;
    }
}
60
flec

Il existe également un module appelé DeepCopy:

https://github.com/myclabs/DeepCopy

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

Vous pouvez également ajouter des filtres pour personnaliser le processus de copie.

8
Ben

Je ne pouvais pas utiliser DeepClone (il nécessite PHP 7.1+), alors j’ai trouvé un moyen plus simple de cloner des relations dans la méthode entity __clone.

$this->tags = new ArrayCollection($this->tags->toArray());
0
Andrew Zhilin

Utilisez simplement php clone mot-clé et vous avez terminé!

$newEntity = clone $oldEntity;

$em = $this->getDoctrine()->getManager();
$em->persist($newEntity);
$em->flush();
0
sadiq