53

我创建了一个AOneToMany相关的实体B,它与OneToMany相关C

我必须克隆这个A实体并将其设置在具有新 ID 的数据库中。此外,所有深层关系也应该用新的 id 克隆。

我尝试过将Aid 设置为null

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

它在表中创建新记录A,但不在Band中C

A我应该怎么做才能制作实体的完整副本?

4

3 回答 3

82

__clone()您必须在实体中 实现一个方法,将 id 设置为 null 并在需要时克隆关系。因为如果您将 id 保留在相关对象中,它会假定您的新实体A与现有实体BC.

克隆方法A

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

B和的克隆方法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

基于 coder4show 的注释,用于 OneToMany 关系的克隆方法在A哪里$this->M是 OneToMany,因此是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;
    }
}
于 2013-01-04T14:16:50.777 回答
9

还有一个模块可以做到这一点,称为 DeepCopy:

https://github.com/myclabs/DeepCopy

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

您还可以添加过滤器来自定义复制过程。

于 2014-11-14T10:52:47.017 回答
2

我无法使用 DeepClone(它需要 php 7.1+),所以我创建了更简单的方法来克隆实体 __clone 方法中的关系

$this->tags = new ArrayCollection($this->tags->toArray());
于 2018-02-28T17:40:54.317 回答