I am trying to implement Embedded Forms (Symfony2, 2.7), with a three layers situation: Job, Task and Tag entities, One2Many relationships. So, what I am trying is just to develop a very basic web application by the Symfony2 framework (really, an exercise to learn Symfony2): I want to display a (html) form to create a Job object/record, with embedded forms to create a couple of related 1:M Tasks, each of the latter with embedded forms to create 1:M Tags, such that all the objects are saved (persisted) at once.Instead, I am not able to persist Tag entities, unless I do it by brute force (see taskController  below), although I am assured Symfony2 should take care of it (see my previous questions). I don't think it is typo, but could be something silly.If you spot something wrong with my code below, I appreciate your help:*****Job.php/** * @ORM\OneToMany(targetEntity=Task, mappedBy=job, cascade={persist} ) */protected $tasks;....../** * Constructor */public function __construct(){    $this->tasks = new \Doctrine\Common\Collections\ArrayCollection();}/** * Add task * * @param \MyName\Bundle\BlogBundle\Entity\Task $task * * @return Job */public function addTask(\MyName\Bundle\BlogBundle\Entity\Task $task){    $this->tasks[] = $task;    return $this;}/** * Get tasks * * @return \Doctrine\Common\Collections\Collection */public function getTasks(){    return $this->tasks;}**** JobController.php/** * Creates a new Job entity. * * @Route(/, name=MyName_Job_create) * @Method(POST) * @Template(MyNameBlogBundle:Job:new.html.twig) */public function createAction(Request $request){    $entity = new Job();    $form = $this->createCreateForm($entity);    $form->handleRequest($request);    if ($form->isValid()) {        $em = $this->getDoctrine()->getManager();        $em->persist($entity);        $em->flush();        return $this->redirect($this->generateUrl('MyName_Job_show', array('id' => $entity->getId())));    }    return array(        'entity' => $entity,        'form'   => $form->createView(),    );}**** JobType.php  /** * @param FormBuilderInterface $builder * @param array $options */public function buildForm(FormBuilderInterface $builder, array $options){    $builder        ->add('title')        ->add('description')    ;}/** * @param OptionsResolverInterface $resolver */public function setDefaultOptions(OptionsResolverInterface $resolver){    $resolver->setDefaults(array(        'data_class' => 'MyName\Bundle\BlogBundle\Entity\Job'        ))    ->setRequired(array(            'em',        ))     ->setAllowedTypes(array(            'em' => 'Doctrine\Common\Persistence\ObjectManager',        ))          ;}**** Task.php/** * @ORM\ManyToOne(targetEntity=Job, inversedBy=tasks ) * @ORM\JoinColumn(name=job_id, referencedColumnName=id) */private $job;....../** * * @ORM\OneToMany(targetEntity=Tag, mappedBy=task, cascade={persist} ) */private $tags;**** TaskController.phpNote. To persist Tags, it seems I still need to setTask(), but I should not: it  should be already  taken care of by Symfony, given the way One2many relationships  has been defined. /** * Creates a new Task entity. * * @Route(/, name=MyName_Task_create) * @Method(POST) * @Template(MyNameBundleBlogBundle:Task:new.html.twig) */public function createAction(Request $request){    $task = new Task();    $form = $this->createCreateForm($task);    $form->handleRequest($request);    $tags = $task->getTags();    if ($form->isValid()) {        $em = $this->getDoctrine()->getManager();      /*  $tags = $task->getTags();        foreach($tags as $tag){       $tag->setTask($task); $em->persist($tag);   // <-- This loop fixes it, but I should need it, setTask should be already taken care of!       }  */        $em->persist($task);        $em->flush();     return $this->redirect($this->generateUrl('MyName_Task_show', array('id' => $task->getId())));    }    return array(        'entity' => $task,        'form'   => $form->createView(),    );}(forms)/** * Creates a form to create a Task entity. * * @param Task $task The entity * * @return \Symfony\Component\Form\Form The form */private function createCreateForm(Task $task)    {EDIT: BELOW SEEMS TO BE WRONG. It works if moved within  NewAction() of root object Job. See my own answer.    $tag1 = new Tag();    $tag1->setTitle('tag1');    $task->addTags($tag1);    $tag2 = new Tag();    $tag2->setTitle('tag2');    $task->addTags($tag2);    $em = $this->getDoctrine()->getEntityManager();    $form = $this->createForm(new TaskType(), $task, array(        'action' => $this->generateUrl('MyName_Task_create'),        'method' => 'POST',        'em' => $em    ));    $form->add('submit', 'submit', array('label' => 'Write Task'));    return $form;  }**** TaskType.php/** * @param FormBuilderInterface $builder * @param array $options */public function buildForm(FormBuilderInterface $builder, array $options){    $entityManager = $options['em'];    $transformer = new JobToIdTransformer($entityManager);    $builder        ->add('job')        ->add('title')        ->add('description')        ->add( $builder->create('job', 'hidden')->addModelTransformer($transformer))        ->add('tags', 'collection', array('type' => new TagType(),      'options'  => array('em' => $entityManager), 'by_reference' => false, 'cascade_validation' => true));}/** * @param OptionsResolverInterface $resolver */public function setDefaultOptions(OptionsResolverInterface $resolver){    $resolver->setDefaults(array(        'data_class' => 'MyName\Bundle\BlogBundle\Entity\Task',        'cascade_validation' => true,    ))     ->setRequired(array(            'em',        ))     ->setAllowedTypes(array(            'em' => 'Doctrine\Common\Persistence\ObjectManager',        ))             ;}**** Tag.php/** * @ORM\ManyToOne(targetEntity=Task, inversedBy=tags) * @ORM\JoinColumn(name=task_id, referencedColumnName=id) */protected $task; /** * Set task * * @param \MyName\Bundle\BlogBundle\Entity\Task $task * * @return Tag */public function setTask(\MyName\Bundle\BlogBundle\Entity\Task $task = null){    $this->task = $task;    return $this;}/** * Get task * * @return \MyName\Bundle\BlogBundle\Entity\Task */public function getTask(){    return $this->task;}public function addTask(Task $task) {     $this->task->add($task);  }**** TagController.php/** * Creates a new Tag entity. * * @Route(/, name=MyName_Tag_create) * @Method(POST) * @Template(MyNameBlogBundle:Tag:new.html.twig) */public function createAction(Request $request)   // Do I need it, if Tags are always created as embedded into a Task?{    $entity = new Tag();    $form = $this->createCreateForm($entity);    $form->handleRequest($request);    if ($form->isValid()) {        $em = $this->getDoctrine()->getManager();        $em->persist($entity);        $em->flush();        return $this->redirect($this->generateUrl('MyName_Tag_show', array('id' => $entity->getId())));    }**** TagType.php /** * @param FormBuilderInterface $builder * @param array $options */public function buildForm(FormBuilderInterface $builder, array $options){   $entityManager = $options['em'];   $transformer = new TaskToIdTransformer($entityManager);    $builder        ->add('titolo')        ->add( $builder->create('task', 'hidden', array('by_reference' => false, 'cascade_validation' => true))->addModelTransformer($transformer))    ;  }    return array(        'entity' => $entity,        'form'   => $form->createView(),    );}
Symfony2 (2.7), Embedded Forms, Persist failure
php;object oriented;symfony2
SOLVED:It seems to be a mistake to insert creation of some (dummy) objects within a createCreateForm action, instead everything works fine if that goes within the New action. (I am not completely sure why)So the following corrected code works fine: /** * Creates a new Job entity. * * @Route(/, name=MyName_Job_create) * @Method(POST) * @Template(MyNameBlogBundle:Job:new.html.twig) */public function createAction(Request $request){    $entity = new Job();    $form = $this->createCreateForm($entity);    $form->handleRequest($request);    if ($form->isValid()) {        $em = $this->getDoctrine()->getManager();        $em->persist($entity);        $em->flush();       return $this->redirect($this->generateUrl('MyName_Job_show', array('id' => $entity->getId())));    }    return array(        'entity' => $entity,        'form'   => $form->createView(),    );}/** * Creates a form to create a Job entity. * * @param Job $entity The entity * * @return \Symfony\Component\Form\Form The form */private function createCreateForm(Job $entity){    $form = $this->createForm(new JobType(), $entity, array(        'action' => $this->generateUrl('MyName_Job_create'),        'method' => 'POST',    ));   $form->add('submit', 'submit', array('label' => 'Create'));    return $form;}/** * Displays a form to create a new Job entity. * * @Route(/new, name=MyName_Job_new) * @Method(GET) * @Template() */public function newAction(){    $job = new Job();    // dummy code - this is here just so that the Task has some tags    // otherwise, this isn't an interesting example    $task1 = new Task();    $task1->setTitle('task1');    $job->addTask($task1);        $tag11 = new Tag();        $tag11->setTitle('tag11');        $task1->addTag($tag11);        $tag12 = new Tag();        $tag12->setTitle('tag12');        $task1->addTag($tag12);    $task2 = new Task();    $task2->setTitle('task2');    $job->addTask($task2);        $tag21 = new Tag();        $tag21->setTitle('tag21');        $task2->addTag($tag21);        $tag22 = new Tag();        $tag22->setTitle('tag22');        $task2->addTag($tag22);    // end dummy code    $form = $this->createCreateForm($job);    return array(        'entity' => $job,        'form'   => $form->createView(),    );}