2013-01-04 22 views
31

Ho creato un'entità A con OneToMany relazione a B, che ha relazione OneToMany a C.Entità Doctrine clone profondo con entità correlate

Devo clonare questa entità A e impostarla nel database con un nuovo ID. Anche tutte le relazioni profonde dovrebbero essere clonate anche con nuovi id.

Che ho ho cercato è quello di impostare A id per null:

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

Crea nuovo record nella tabella A, ma non in B e C.

Cosa devo fare per creare una copia completa dell'entità A?

risposta

47

È necessario implementare un metodo __clone() nelle entità che imposta l'ID su null e clona le relazioni se lo si desidera. Perché se si mantiene l'id nell'oggetto correlato, si presuppone che la nuova entità A abbia una relazione con le entità esistenti B e C.

Clone-metodo per A:

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

Clone-metodo per B e 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

Sulla base del commento di coder4 mostrare un clone metodo per un rapporto OneToMany su A dove $this->M è OneToMany e quindi un 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

L'unico problema con questo è, non sembra lavorare su OneToMany, qualche idea perché? – coder4show

+1

@ coder4show è perché si sta clonando 'ArrayCollection' e non gli elementi in esso. Ho aggiunto un metodo clone per una relazione OneToMany. – flec

+0

In questo esempio, la relazione OneToMany non verrà clonata correttamente, poiché le entità correlate clonate si riferiscono ancora alla vecchia entità. Vedi [questa risposta] (http://stackoverflow.com/a/28313673/3215645) per un esempio operativo – Richard

6

C'è anche un modulo che farà questo chiamato deepcopy:

https://github.com/myclabs/DeepCopy

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

È inoltre possibile aggiungere filtri per personalizzare il processo di copia.

+0

Ciao @ Ben puoi dare un'occhiata a [questo] (http://stackoverflow.com/questions/28650001/clone-entity-in-cascade-mode?noredirect=1#comment45641837_28650001) – ReynierPM

+1

Ho trovato questo incredibilmente bacato e è più veloce semplicemente rotolare i propri metodi 'clone' –

0

non ero in grado di utilizzare DeepClone (si richiede PHP 7.1+), così ho fondato il modo più semplice per clonare le relazioni nel metodo __clone entità

$this->tags = new ArrayCollection($this->tags->toArray()); 
Problemi correlati