A
との関係を持つOneToMany
関係を持つエンティティB
を作成しました。これらの関係はOneToMany
とC
の関係にあります。
このA
エンティティのクローンを作成し、新しいIDでデータベースに設定する必要があります。また、すべてのディープリレーションも新しいIDで複製する必要があります。
私が試したのは、A
idをnull
に設定することです:
$A = clone $A_original;
$A->setId(null);
$em->persist($A);
A
テーブルに新しいレコードを作成しますが、B
およびC
には作成しません。
A
エンティティの完全なコピーを作成するにはどうすればよいですか?
エンティティに__clone()
メソッドを実装して、IDをnullに設定し、必要に応じてリレーションを複製する必要があります。関連オブジェクトにidを保持する場合、新しいエンティティA
が既存のエンティティB
およびC
と関係があると想定されるためです。
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のコメントに基づいて、A
上のOneToMany関係のクローンメソッドを示します。ここで、$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;
}
}
DeepCopyと呼ばれるこれを行うモジュールもあります。
https://github.com/myclabs/DeepCopy
$deepCopy = new DeepCopy();
$myCopy = $deepCopy->copy($myObject);
フィルターを追加して、コピープロセスをカスタマイズすることもできます。
DeepCloneを使用できなかったため(php 7.1以降が必要です)、エンティティ__cloneメソッドでリレーションを複製するより簡単な方法を見つけました。
$this->tags = new ArrayCollection($this->tags->toArray());
Php clone
キーワードを使用するだけで完了です!
$newEntity = clone $oldEntity;
$em = $this->getDoctrine()->getManager();
$em->persist($newEntity);
$em->flush();