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
?
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;
}
}
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.
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());
Utilisez simplement php clone
mot-clé et vous avez terminé!
$newEntity = clone $oldEntity;
$em = $this->getDoctrine()->getManager();
$em->persist($newEntity);
$em->flush();