简体   繁体   English

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

[英]Unable to persist complex entity graph in Symfony2/Doctrine2

I'm a bit limited in the details I can provide due to a NDA, so please bear with me. 由于保密协议,我在提供的详细信息上受到了限制,请耐心等待。

I have a complex entity graph. 我有一个复杂的实体图。 It consists of: 它包括:

  • A 1-to-1 relationship between a Parent and Child . ParentChild之间的Parent关系。
  • The Child contains an ArrayCollection of FooChild entities. Child包含FooChild实体的ArrayCollection Cascade all. 级联所有。
  • FooChild represents a many-to-many join table between Foo and Child , but also contains some metadata that Child needs to track. FooChild表示FooChild之间的多对多FooChild表,但还包含一些Child需要跟踪的元数据。 Cascade persist on each side ( Foo and Child ) 级联在每一侧都保持不变( FooChild
  • Parent s aren't required to have a Child . Parent不需要生Child

To be 100% clear regarding FooChild , the relationship is many-to-many, but because of the metadata, it contains many-to-one relationship definitions: 为了100%明确FooChild ,该关系是多对多的,但是由于元数据的缘故,它包含多对一的关系定义:

/**
 * @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
}

Okay, so with that structure, on the Parent edit page, I created the option for someone to add a Child to it and populate it with FooChild s with the Symfony prototype mechanism seen here . 好了,与结构,在对Parent编辑页面,我创建了一个人的添加选项Child用它和填充它FooChild s的看到Symfony的原型机制这里 When I attempt to submit the rather large form, I get the following exception: 当我尝试提交较大的表单时,出现以下异常:

Entity of type MyBundle\\Entity\\FooChild has identity through a foreign entity MyBundle\\Entity\\Child, however this entity has no identity itself. MyBundle \\ Entity \\ FooChild类型的实体通过外部实体MyBundle \\ Entity \\ Child具有标识,但是该实体本身没有标识。 You have to call EntityManager#persist() on the related entity and make sure that an identifier was generated before trying to persist 'MyBundle\\Entity\\FooChild'. 您必须在相关实体上调用EntityManager#persist()并确保在尝试持久存储“ MyBundle \\ Entity \\ FooChild”之前已生成标识符。 In case of Post Insert ID Generation (such as MySQL Auto-Increment or PostgreSQL SERIAL) this means you have to call EntityManager#flush() between both persist operations. 在生成后插入ID(例如MySQL自动增量或PostgreSQL SERIAL)的情况下,这意味着您必须在两个持久化操作之间调用EntityManager#flush()。

The thing is, I've attempted to persist the various parts of this graph in different orders, and the exception still remains. 事实是,我试图以不同顺序保留该图的各个部分,但仍然存在异常。 My current attempt is: 我目前的尝试是:

$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();
}

The exception is thrown at the first attempt to persist, in the foreach. 在foreach中首次尝试持久化时会抛出异常。 Like I said before, I've swapped the order of what gets persisted when several times, but it hasn't made a difference. 就像我之前说过的,我已经交换了多次保留的顺序,但是并没有改变。 I'm not sure what else to try. 我不确定还有什么尝试。

I had an initial solution of removing the Child 's form type and having the Parent 's form type handle unmapped (very important) FooChild entries. 我最初的解决方案是删除Child的表单类型,并取消对Parent的表单类型句柄的映射(非常重要) FooChild条目。 Then, in the controller, I had: 然后,在控制器中,我有:

$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
}

It worked, but I ran into some other non-related issues, so I'm currently reorganizing my schema. 它起作用了,但是我遇到了其他一些不相关的问题,所以我目前正在重组我的架构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM