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
andChild
. - The
Child
contains anArrayCollection
ofFooChild
entities. Cascade all. -
FooChild
represents a many-to-many join table betweenFoo
andChild
, but also contains some metadata thatChild
needs to track. Cascade persist on each side (Foo
andChild
) -
Parent
s aren't required to have aChild
.
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 FooChild
s 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.