2013-01-04 69 views
31

我已創建實體AOneToMany關係到B,其關係爲OneToManyC具有相關實體的深克隆主義實體

我必須克隆這個A實體並將其設置在數據庫中,並帶有新的ID。同樣所有深層次的關係也應該用新的ID進行克隆。

我有什麼企圖是設置A id來null

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

它在A表中創建新的記錄,但在BC不一樣。

我應該怎麼做才能製作A實體的完整副本?

回答

47

如果需要,您必須在您的實體中實施__clone()方法,該方法將id設置爲null並克隆關係。因爲如果您將ID保留在相關對象中,它會假定您的新實體A與現有實體BC有關係。爲A

克隆法:爲BC

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

克隆法:基於coder4的評論

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

顯示上A一個一對多關係的克隆方法,其中$this->M是一對多,因此一個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

是,它似乎與這個唯一的問題不工作OneToMany,任何想法爲什麼? – coder4show

+1

@ coder4show,這是因爲您正在克隆ArrayCollection而不是其中的元素。我爲OneToMany關係添加了一個克隆方法。 – flec

+0

在這個例子中,OneToMany關係不會被克隆,因爲克隆的相關實體仍然引用舊的實體。請參閱[這個答案](http://stackoverflow.com/a/28313673/3215645)爲一個工作示例 – Richard

6

還有一個模塊,將做到這叫做deepcopy的:

https://github.com/myclabs/DeepCopy

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

您也可以添加過濾器來自定義複製過程。

+0

嗨@Ben你可以看看[這](http://stackoverflow.com/questions/28650001/clone-entity-in-cascade-mode?noredirect=1#comment45641837_28650001) – ReynierPM

+1

我發現這個令人難以置信的越野車和它更快地推出自己的「克隆」方法 –

0

我不是能夠使用DeepClone(它需要PHP 7.1+),所以我創辦了更簡單的方法來克隆實體__clone方法關係

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