由于保密协议,我能提供的细节有点有限,所以请耐心等待。
我有一个复杂的实体图。它包括:
-
Parent
和Child
之间的1对1关系。 -
Child
包含FooChild
实体中的ArrayCollection
。级联。 -
FooChild
表示Foo
和Child
之间的多对多连接表,但也包含Child
需要跟踪的一些元数据。级联在每侧(Foo
和Child
)持续 -
Parent
s不需要有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
。当我尝试提交相当大的表单时,得到以下异常:
MyBundle'Entity'FooChild类型的实体通过一个外部实体MyBundle'Entity'Child具有身份,但是这个实体本身没有身份。你必须在相关实体上调用EntityManager#persist(),并确保在尝试持久化"MyBundle' entity 'FooChild"之前生成一个标识符。在Post Insert ID生成的情况下(比如MySQL的Auto-Increment或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中第一次尝试持久化时抛出异常。就像我之前说的,我已经交换了几次持久化的顺序,但是没有什么不同。我不知道还能尝试什么
我有一个最初的解决方案,删除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
}
它工作了,但我遇到了一些其他不相关的问题,所以我目前正在重新组织我的模式