方案
class Foo
{
[...]
/**
*@ORM\OneToMany(targetEntity="Bar", mappedBy="foo", cascade={"persist"}, orphanRemoval=true)
*/
protected $bars;
}
class Bars
{
[...]
/**
*@ORM\ManyToOne(targetEntity="Foo", inversedBy="bars")
*/
protected $foo;
[...]
public function setFoo(Foo $foo)
{
$this->foo = $foo;
$foo->addBars($this); //PAY ATTENTION TO THAT LINE
return $this;
}
}
好的,我们假设我有一个FormType来保持Foo
并添加或删除Bars
class FooType
{
[...]
$builder
->add('bars', 'collection', array(
[...]
'allow_add' => true,
'allow_delete' => true,
'prototype_data' => new Bar(),
}
如果我没有指定orphanRemoval=true
选项,那么当我在没有Bar
的情况下发布表单时,我需要做一些手动的额外工作来从Foo
删除Bar
的实体在那里。我不会包含代码,因为它有效并且不是问题。
一旦我使用orphanRemoval=true
(注释掉“额外的工作代码,基本上在绑定表单之前检查数据库条并删除不再发布的条形图),就会发生一些奇怪的事情:无论我是否尝试要从Bar
添加或删除FooType
,结果是Foo
和Bar
(s)之间的每个关系都被销毁。
如果我将$foo->addBars($this);
注释为Bar
的{{1}}方法,则一切正常。
问题
setFoo(Foo $foo)
(如果可能?)答案 0 :(得分:0)
来自Doctrine Docs
当使用orphanRemoval = true选项时,Doctrine假设这些实体是私有的,并且不会被其他实体重用。如果您忽略了这个假设,即使您将孤立实体分配给另一个实体,您的实体也会被Doctrine删除
从page
删除book
后,所有引用都已删除,且两者之间没有关系
您可以尝试从控制器中调用addBars($this);
,看看它是如何工作的
答案 1 :(得分:0)
问题在于by_reference
属性:如果没有这个属性,事情会变得混乱,而且学说似乎无法处理这种情况。
解决方案
class FooType
{
[...]
$builder
->add('bars', 'collection', array(
[...]
'allow_add' => true,
'allow_delete' => true,
'prototype_data' => new Bar(),
'by_reference' => false,
}