无法在Symfony2 / Doctrine2中保留复杂的实体图

时间:2014-07-29 21:10:10

标签: php symfony doctrine-orm

由于NDA,我可以提供的细节有点受限,所以请耐心等待。

我有一个复杂的实体图。它包括:

  • ParentChild之间的一对一关系。
  • Child包含ArrayCollectionFooChild个实体。全部级联。
  • FooChild代表FooChild之间的多对多联接表,但也包含Child需要跟踪的一些元数据。级联持续存在(FooChild
  • Parent不需要Child

关于FooChild 100%明确,关系是多对多关系,但由于元数据,它包含多对一关系定义:

/**
 * @ORM\Entity
 * @ORM\Table(name="foo_children", indexes={
 *      @ORM\Index(name="fooid_idx", columns={"foo_id"}),
 *      @ORM\Index(name="childid_idx", columns={"child_id"}),
 * })
 */

class FooChild
{
    /**
     * @ORM\Id()
     * @ORM\ManyToOne(targetEntity="Foo", cascade={"persist"})
     * @ORM\JoinColumn(name="foo_id", referencedColumnName="id", nullable=false)
     */
    protected $foo;

    /**
     * @ORM\Id()
     * @ORM\ManyToOne(targetEntity="Child", inversedBy="fooChildren", cascade={"persist"})
     * @ORM\JoinColumn(name="child_id", referencedColumnName="id", nullable=false)
     */
    protected $child;

    /**
     * @ORM\Column(type="smallint")
     */
    private $count;

    // methods
}

好的,对于这种结构,在Parent编辑页面上,我为某人添加Child创建了一个选项,并使用Symfony原型用FooChild填充它机制见here。当我尝试提交相当大的表单时,我得到以下异常:

  

MyBundle \ Entity \ FooChild类型的实体通过外部实体MyBundle \ Entity \ Child具有标识,但是此实体本身没有标识。您必须在相关实体上调用EntityManager#persist(),并确保在尝试保留“MyBundle \ Entity \ FooChild”之前生成了标识符。如果生成后插入ID(例如MySQL自动增量或PostgreSQL SERIAL),这意味着您必须在两个持久操作之间调用EntityManager#flush()。

问题是,我试图以不同的顺序保留此图的各个部分,但例外仍然存在。我目前的尝试是:

$form = $this->createForm(new ParentType(), $parent);

if ($request->getMethod() == 'POST') {
    $form->handleRequest($request);

    if ($form->has('child')) {
        $data = $form->getData();
        $child = $data->getChild();
        $fooChildren = $child->getFooChildren();

        foreach ($fooChildren as $fc) {
            $em->persist($fc);
            $em->flush();
        }

        $em->persist($child);
        $em->flush();
    }

    $em->persist($parent);
    $em->flush();
}

在foreach的第一次尝试中,会抛出异常。就像我之前说的那样,我已经多次交换了持久化的顺序,但它并没有产生任何影响。我不知道还有什么可以尝试的。

1 个答案:

答案 0 :(得分:0)

我有一个初步的解决方案,即删除Child的表单类型并让Parent的表单类型处理取消映射(非常重要)FooChild条目。然后,在控制器中,我有:

$em->persist($parent);
$em->flush();

if ($form->has('fooChildren')) {
    $child = new Child();
    $child->setParent($parent);

    $em->persist($child);
    $em->flush();

    // run through the FooChild entites and add them to the child
}

虽然有效,但我遇到了其他一些与此无关的问题,所以我目前正在重组我的架构。