dongyijing2353 2014-07-29 21:10
浏览 48
已采纳

无法在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.
  • The Child contains an ArrayCollection of FooChild entities. Cascade all.
  • FooChild represents a many-to-many join table between Foo and Child, but also contains some metadata that Child needs to track. Cascade persist on each side (Foo and Child)
  • Parents aren't required to have a 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:

/**
 * @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 FooChilds with the Symfony prototype mechanism seen here. 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. 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'. 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.

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. 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.

  • 写回答

1条回答 默认 最新

  • doulu4534 2014-07-30 20:59
    关注

    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. 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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 MATLAB动图问题
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名