Php 无法在Symfony2/Doctrine2中持久化复杂实体图
由于保密协议的原因,我能提供的细节有点有限,所以请耐心等待 我有一个复杂的实体图。它包括:Php 无法在Symfony2/Doctrine2中持久化复杂实体图,php,symfony,doctrine-orm,Php,Symfony,Doctrine Orm,由于保密协议的原因,我能提供的细节有点有限,所以请耐心等待 我有一个复杂的实体图。它包括: 父项和子项之间的一对一关系 Child包含FooChild实体的ArrayCollection。全部级联 FooChild表示Foo和Child之间的多对多联接表,但也包含一些Child需要跟踪的元数据。级联在每一侧持续(Foo和Child) 父项不需要有子项 关于FooChild,要100%清楚,关系是多对多的,但由于元数据,它包含多对一关系定义: /** * @ORM\Entity * @OR
和父项
之间的一对一关系李>子项
包含Child
实体的FooChild
。全部级联ArrayCollection
表示FooChild
和Foo
之间的多对多联接表,但也包含一些Child
需要跟踪的元数据。级联在每一侧持续(Child
和Foo
)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
edit页面上,我为某人创建了一个选项,可以向其添加Child
,并使用看到的Symfony原型机制填充FooChild
s。当我尝试提交相当大的表单时,会出现以下异常:
MyBundle\Entity\FooChild类型的实体通过外部实体MyBundle\Entity\Child具有标识,但该实体本身没有标识。您必须在相关实体上调用EntityManager#persist(),并确保在尝试持久化“MyBundle\entity\FooChild”之前生成了标识符。在生成插入后ID(如MySQL自动增量或PostgreSQL串行)的情况下,这意味着您必须在两个持久化操作之间调用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中,在第一次尝试持久化时抛出异常。正如我之前所说,我已经多次交换了持久化的顺序,但这并没有产生任何影响。我不确定还能尝试什么。我有一个初始解决方案,删除
子项的表单类型,并取消映射父项的表单类型句柄(非常重要)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
}
它起作用了,但我遇到了一些其他不相关的问题,因此我目前正在重新组织我的模式。您确定传递给persist方法的变量确实是实体的实例吗?在您的foreach
中,print gettype($fc)
的输出是什么,如果它是对象,print getu class($fc)的输出是什么代码>是,它们是我的实体的实例。PhpStorm调试器验证。如果不违反保密协议,我无法发布屏幕截图。您是否尝试持久化并刷新$parent
然后$child
然后$fooChildren
?我认为您需要从$parent
中删除$child
,然后持久化并刷新$parent
,因为它不需要孩子,对$child
和$fooChildren
执行同样的操作不是最佳的,但这可能是一个很好的开始,以了解到底是什么导致了错误