2013-01-04 156 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());