title: Symfony2 try to insert ManyToMany relation before insert one part of both sides
body: <p>I have this Entities:</p>
  
  <pre><code>&lt;?php
  
  namespace ProductBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Gedmo\Mapping\Annotation as Gedmo;
  use ProductBundle\DBAL\Types\StatusType;
  use ProductBundle\DBAL\Types\FieldType;
  use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
  
  /**
   * @ORM\Entity
   * @ORM\Table(name="product_detail")
   */
  class ProductDetail {
  
      /**
       * @ORM\Id
       * @ORM\Column(type="integer")
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      protected $id;
  
      /**
       * @ORM\ManyToOne(targetEntity="ProductDetail")
       * @ORM\JoinColumn(name="parent", referencedColumnName="id")
       */
      protected $parent;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      protected $description;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      protected $label;
  
      /**
       * @var string $field_type
       * @DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\FieldType")
       * @ORM\Column(name="field_type", type="FieldType", nullable=false)
       */
      protected $field_type;
  
      /**
       * @ORM\Column(name="values_text", type="string")
       */
      protected $values_text;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      protected $measure_unit;
  
      /**
       * @var string $status
       * @DoctrineAssert\Enum(entity="ProductBundle\DBAL\Types\StatusType")
       * @ORM\Column(name="status", type="StatusType", nullable=false)
       */
      protected $status;
  
      /**
       * @Gedmo\Timestampable(on="create")
       * @ORM\Column(name="created", type="datetime")
       */
      protected $created;
  
      /**
       * @Gedmo\Timestampable(on="update")
       * @ORM\Column(name="modified", type="datetime")
       */
      protected $modified;
  
      /**
       * @ORM\ManyToMany(targetEntity="CategoryBundle\Entity\Category", inversedBy="pd_detail")
       * @ORM\JoinTable(name="product_detail_has_category",
       *      joinColumns={@ORM\JoinColumn(name="category", referencedColumnName="id")},
       *      inverseJoinColumns={@ORM\JoinColumn(name="detail", referencedColumnName="id")}
       *      )
       */
      protected $category;
  
      /**
       * @ORM\ManyToMany(targetEntity="ProductBundle\Entity\DetailGroup", inversedBy="productDetail")
       * @ORM\JoinTable(name="detail_group_has_product_detail",
       *      joinColumns={@ORM\JoinColumn(name="group", referencedColumnName="id")},
       *      inverseJoinColumns={@ORM\JoinColumn(name="detail", referencedColumnName="id")}
       *      )
       */
      protected $detail_group;
  
      public function __construct() {
          $this-&gt;detail_group = new \Doctrine\Common\Collections\ArrayCollection();
          $this-&gt;category = new \Doctrine\Common\Collections\ArrayCollection();
      }
  
      public function getId() {
          return $this-&gt;id;
      }
  
      public function setParent(ProductDetail $parent = null) {
          $this-&gt;parent = $parent;
      }
  
      public function getParent() {
          return $this-&gt;parent;
      }
  
      public function setDescription($description) {
          $this-&gt;description = $description;
      }
  
      public function getDescription() {
          return $this-&gt;description;
      }
  
      public function setLabel($label) {
          $this-&gt;label = $label;
      }
  
      public function getLabel() {
          return $this-&gt;label;
      }
  
      public function setFieldType($field_type) {
          $this-&gt;field_type = $field_type;
      }
  
      public function getFieldType() {
          return $this-&gt;field_type;
      }
  
      public function setValuesText($values_text) {
          $this-&gt;values_text = $values_text;
      }
  
      public function getValuesText() {
          return $this-&gt;values_text;
      }
  
      public function setMeasureUnit($measure_unit) {
          $this-&gt;measure_unit = $measure_unit;
      }
  
      public function getMeasureUnit() {
          return $this-&gt;measure_unit;
      }
  
      public function setStatus($status) {
          $this-&gt;status = $status;
      }
  
      public function getStatus() {
          return $this-&gt;status;
      }
  
      public function setCreated($param) {
          $this-&gt;created = $param;
          return true;
      }
  
      public function getCreated() {
          return $this-&gt;created;
      }
  
      public function setModified($param) {
          $this-&gt;modified = $param;
          return true;
      }
  
      public function getModified() {
          return $this-&gt;modified;
      }
  
      public function setCategory(Category $category) {
          $this-&gt;category[] = $category;
      }
  
      public function getCategory() {
          return $this-&gt;category;
      }
  
      public function setDetailGroup(DetailGroup $detailGroup) {
          $this-&gt;detail_group[] = $detailGroup;
      }
  
      public function getDetailGroup() {
          return $this-&gt;detail_group;
      }
  
  }
  </code></pre>
  
  <p>
  
  <pre><code>namespace ProductBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Gedmo\Mapping\Annotation as Gedmo;
  use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;
  
  /**
   * @ORM\Entity
   * @ORM\Table(name="detail_group")
   */
  class DetailGroup {
  
      /**
       * @ORM\Id
       * @ORM\Column(type="integer")
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      protected $id;
  
      /**
       * @ORM\ManyToOne(targetEntity="DetailGroup")
       * @ORM\JoinColumn(name="parent", referencedColumnName="id")
       */
      protected $parent;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      protected $name;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      protected $description;
  
      /**
       * @Gedmo\Timestampable(on="create")
       * @ORM\Column(name="created", type="datetime")
       */
      protected $created;
  
      /**
       * @Gedmo\Timestampable(on="update")
       * @ORM\Column(name="modified", type="datetime")
       */
      protected $modified;
  
      /**
       * @ORM\ManyToMany(targetEntity="ProductBundle\Entity\ProductDetail", mappedBy="detail_group", cascade={"all"})
       */
      protected $productDetail;
  
      public function __construct() {
          $this-&gt;productDetail = new \Doctrine\Common\Collections\ArrayCollection();
      }
  
      public function getId() {
          return $this-&gt;id;
      }
  
      public function setParent(DetailGroup $parent = null) {
          $this-&gt;parent = $parent;
      }
  
      public function getParent() {
          return $this-&gt;parent;
      }
  
      public function setName($name) {
          $this-&gt;name = $name;
      }
  
      public function getName() {
          return $this-&gt;name;
      }
  
      public function setDescription($description) {
          $this-&gt;description = $description;
      }
  
      public function getDescription() {
          return $this-&gt;description;
      }
  
      public function setCreated($param) {
          $this-&gt;created = $param;
          return true;
      }
  
      public function getCreated() {
          return $this-&gt;created;
      }
  
      public function setModified($param) {
          $this-&gt;modified = $param;
          return true;
      }
  
      public function getModified() {
          return $this-&gt;modified;
      }
  
      public function setProductDetail(ProductDetail $productDetail) {
          $this-&gt;productDetail[] = $productDetail;
      }
  
      public function getProductDetail() {
          return $this-&gt;productDetail;
      }
  
  }
  </code></pre>
  
  <p>This is my <code>ProductDetailType.php</code> form:</p>
  
  <pre><code>&lt;?php
  
  namespace ProductBundle\Form;
  
  use Symfony\Component\Form\AbstractType;
  use Symfony\Component\Form\FormBuilderInterface;
  use Symfony\Component\OptionsResolver\OptionsResolverInterface;
  
  class ProductDetailType extends AbstractType {
  
      public function buildForm(FormBuilderInterface $builder, array $options) {
          $builder
                  -&gt;add('category', 'entity', array('class' =&gt; 'CategoryBundle:Category', 'property' =&gt; 'name', 'required' =&gt; false, 'multiple' =&gt; true, 'expanded' =&gt; false))
                  -&gt;add('detail_group', 'entity', array('class' =&gt; 'ProductBundle:DetailGroup', 'property' =&gt; 'name', 'required' =&gt; false, 'multiple' =&gt; true, 'expanded' =&gt; false))
                  -&gt;add('parent', 'entity', array('class' =&gt; 'ProductBundle:ProductDetail', 'property' =&gt; 'label', 'required' =&gt; false))
                  -&gt;add('description', 'text', array('required' =&gt; false))
                  -&gt;add('label')
                  -&gt;add('field_type', 'choice', ['choices' =&gt; \ProductBundle\DBAL\Types\FieldType::getChoices()])
                  -&gt;add('values_text', 'collection', array('type' =&gt; 'text', 'allow_add' =&gt; true, 'allow_delete' =&gt; true, 'by_reference' =&gt; false))
                  -&gt;add('measure_unit', 'text', array('required' =&gt; false))
                  -&gt;add('status', 'choice', ['choices' =&gt; \ProductBundle\DBAL\Types\StatusType::getChoices()]);
      }
  
      public function setDefaultOptions(OptionsResolverInterface $resolver) {
          $resolver-&gt;setDefaults(array(
              'data_class' =&gt; 'ProductBundle\Entity\ProductDetail'
          ));
      }
  
      public function getName() {
          return 'prod_detail_create';
      }
  
  }
  </code></pre>
  
  <p>And this is my <code>createAction()</code>:</p>
  
  <pre><code>/**
   * Handle product details creation
   *
   * @Route("/product_detail/create", name="product_detail_create")
   * @Method("POST")
   * @Template("ProductBundle:ProductDetail:new.html.twig")
   */
  public function createAction(Request $request) {
      $entity = new ProductDetail();
      $form = $this-&gt;createForm(new ProductDetailType(), $entity);
      $form-&gt;handleRequest($request);
  
      if ($form-&gt;isValid()) {
          $em = $this-&gt;getDoctrine()-&gt;getManager();
          $entity-&gt;setValuesText(serialize($form-&gt;get('values_text')-&gt;getData()));
          $em-&gt;persist($entity);
          $em-&gt;flush();
  
          return $this-&gt;redirect($this-&gt;generateUrl('product_detail_list'));
      }
  
      return $this-&gt;render('ProductBundle:ProductDetail:new.html.twig', array(
                  'entity' =&gt; $entity,
                  'form' =&gt; $form-&gt;createView(),
      ));
  }
  </code></pre>
  
  <p>When I try to insert new records I get this errors:</p>
  
  <blockquote>
    <p>An exception occurred while executing 'INSERT INTO
    product_detail_has_category (category, detail) VALUES (?, ?)' with
    params [7, 2]:</p>
    
    <p>SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
    update a child row: a foreign key constraint fails
    (<code>product_detail_has_category</code>, CONSTRAINT
    <code>fk_product_detail_has_category_product_detail1</code> FOREIGN KEY
    (<code>detail</code>) REFERENCES <code>product_detail</code> (<code>id</code>) ON UPDATE CASCADE)</p>
  </blockquote>
  
  <p>I check the logs and see this:</p>
  
  <pre><code>DEBUG - "START TRANSACTION"
  DEBUG - INSERT INTO product_detail (description, label, field_type, values_text, measure_unit, status, created, modified, parent) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
  DEBUG - INSERT INTO product_detail_has_category (category, detail) VALUES (?, ?)
  DEBUG - "ROLLBACK" 
  </code></pre>
  
  <p>I don't know why it doesn't insert product_detail and the tries to create the relation, what is wrong?</p>