2013-01-04 10 views
31

Ich habe eine Entität A mit OneToMany Beziehung zu B, die Beziehung OneToMany zu C haben.Deep Clone Doctrine Entity mit verwandten Entitäten

Ich muss dieses A Entity klonen und es in der Datenbank mit neuer ID setzen. Auch alle tiefen Beziehungen sollten mit neuen IDs geklont werden.

Was haben habe ich versucht, ist A-ID auf null:

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

Es neuen Rekord in A Tabelle erstellt, aber nicht in B und C.

Was soll ich tun, um eine vollständige Kopie von A Einheit zu machen?

Antwort

47

Sie müssen eine __clone()-Methode in Ihren Entities implementieren, die die ID auf null setzt und die Beziehungen klont, falls gewünscht. Wenn Sie die ID im zugehörigen Objekt beibehalten, wird davon ausgegangen, dass Ihre neue Entität A eine Beziehung zu den vorhandenen Entitäten B und C hat.

Clone-Methode für A:

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

Clone-Methode für B und 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

Basierend auf den Kommentar von coder4 zeigen eine Klon-Methode für eine OneToMany Beziehung auf A wo $this->M OneToMany ist und daher ein 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; 
    } 
} 
+0

Das einzige Problem dabei ist, es scheint nicht zu Arbeit an OneToMany, irgendwelche Ideen warum? – coder4show

+1

@ coder4show Das liegt daran, dass Sie die'ArrayCollection' und nicht die darin enthaltenen Elemente klonen. Ich habe eine Clone-Methode für eine OneToMany-Beziehung hinzugefügt. – flec

+0

In diesem Beispiel wird die OneToMany-Beziehung nicht korrekt geklont, da sich die geklonten verwandten Entitäten immer noch auf die alte Entität beziehen. Siehe [diese Antwort] (http://stackoverflow.com/a/28313673/3215645) für ein funktionierendes Beispiel – Richard

6

Es gibt auch ein Modul, das diese genannt deep tun:

https://github.com/myclabs/DeepCopy

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

Sie können auch Filter hinzufügen, um den Kopiervorgang anzupassen.

+0

Hallo @ Ben können Sie einen Blick auf [diese] nehmen (http://stackoverflow.com/questions/28650001/clone-entity-in-cascade-mode?noredirect=1#comment45641837_28650001) – ReynierPM

+1

ich gefunden habe, diese unglaublich Buggy und es ist schneller, nur Ihre eigenen "Klon" -Methoden zu rollen –

0

Ich war nicht fähig DeepClone zu verwenden (es PHP 7.1+ erforderlich), so dass ich gegründet einfache Art und Weise

Beziehungen in Unternehmen __clone Verfahren zu klonen
$this->tags = new ArrayCollection($this->tags->toArray()); 
Verwandte Themen