Doctrine的孤儿撤消奇怪的行为?

时间:2015-08-20 09:48:38

标签: symfony doctrine-orm

方案

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,结果是FooBar(s)之间的每个关系都被销毁。

如果我将$foo->addBars($this);注释为Bar的{​​{1}}方法,则一切正常。

问题

  1. 为什么会这样?
  2. 如何在不删除setFoo(Foo $foo)(如果可能?)
  3. 的情况下解决问题

2 个答案:

答案 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,
}