バックグラウンド:
私のアプリケーションには、自己参照 ManyToOne
関連を持つエンティティがあります(多くの子が単一の親を指すことができます)。また、Doctrine ORM を使用して一度に多くのエンティティを一括更新する機能があります。多くのエンティティが読み込まれるためにパフォーマンスが劇的に低下するのを防ぐために、エンティティdetach
が更新された後に I エンティティを読み込みます。
問題:
私が子供を持っていて後にそれらの子供のいずれかを更新しようとdetach
するエンティティが、それがもう親を知らないと不平を言うとき。子供を更新しようとする前に親のエンティティであっても。merge
質問:
親エンティティをデタッチするときに何が間違っていますか? 親列で cascade="merge" および/または "detach" を実行しようとしましたが、保持しようとすると、Doctrine は親が不明なエンティティであるとまだ不平を言っています。
これを再現する簡単な例をモックアップしました。下記参照。
テストコード:
エンティティ\Thing.php
/**
* @ORM\Entity()
* @ORM\Table(name="things")
*/
class Thing
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Thing", inversedBy="children", cascade={"detach","merge"})
* @ORM\JoinColumn(name="parentId", referencedColumnName="id", onDelete="SET NULL")
*/
protected $parent;
/**
* @ORM\OneToMany(targetEntity="Thing", mappedBy="parent")
*/
protected $children;
/**
* @ORM\Column(type="string", length=64)
*/
protected $name;
public function __construct($name = null)
{
$this->children = new ArrayCollection();
$this->name = $name;
}
// .. SNIP ...
}
テスト アクション:
public function testThingAction($_route)
{
$em = $this->getDoctrine()->getEntityManager();
$repo = $em->getRepository('AcmeThingBundle:Thing');
// simple setup of a couple things in the DB
$t1 = $repo->findByName('Thing1');
if (!$t1) {
$t1 = new Thing('Thing1');
$t2 = new Thing('Thing2');
$t2->setParent($t1);
$em->persist($t1);
$em->persist($t2);
$em->flush();
return $this->redirect($this->generateUrl($_route));
}
list($t1, $t2) = $repo->findAll();
// detach and re-merge Thing1
// This should cause Thing1 to be removed and then re-added
// to the doctrine's known entities; but it doesn't!?
$em->detach($t1);
$em->merge($t1);
// try to update T2
$t2->setName('Thing2 - ' . time());
$em->persist($t2);
// will fail with:
// A new entity was found through the relationship Thing#parent
$em->flush();
return array();
}