title: Symfony2 form and Doctrine2 - update foreign key in assigned entities fails
body: <p>I have profiles and studies. One person can finish many studies. The form renders correctly. There is a button "Add new study" and with jQuery I add another subform based on data-prototype and this works well. When I submit such a form with new subforms I get an database error </p>
  
  <pre><code>Integrity constraint violation: 1048 Column 'profile_id' cannot be null 
  </code></pre>
  
  <p>I understand this error but I don't know how to get rid of it. I know I can update collection of studies after binding in controller but I hope there is a way to configure it properly in annotations. When I only update entities everything works fine.</p>
  
  <p>The code is:</p>
  
  <pre><code>class Profile {
      /**
       * @var integer $profileId
       *
       * @ORM\Column(name="profile_id", type="integer", nullable=false)
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="IDENTITY")
       */
      private $profileId;
  ...
      /**
       *
       * @var Study
       * @ORM\OneToMany(targetEntity="Study", mappedBy="profile", cascade={"persist", "remove"})
       */
      private $study;
  
      public function __construct()
      {
          $this-&gt;study = new \Doctrine\Common\Collections\ArrayCollection();
      }
  ...
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>    class Study {
      /**
       * @var integer $studyId
       *
       * @ORM\Column(name="study_id", type="integer", nullable=false)
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="IDENTITY")
       */
      private $studyId;
  ...
      /**
       * @var Profile
       *
       * @ORM\ManyToOne(targetEntity="Profile")
       * @ORM\JoinColumns({
       *   @ORM\JoinColumn(name="profile_id", referencedColumnName="profile_id")
       * })
       */
      private $profile;
  ...
  }
  </code></pre>
  
  <p>with s(g)etters. Underlaying database structure is</p>
  
  <pre><code>CREATE TABLE IF NOT EXISTS `profile` (
    `profile_id` int(11) NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`profile_id`),
  ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
  
  CREATE TABLE IF NOT EXISTS `study` (
    `study_id` int(11) NOT NULL AUTO_INCREMENT,
    `profile_id` int(11) NOT NULL,
    PRIMARY KEY (`study_id`),
  ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
  
  ALTER TABLE `study`
    ADD CONSTRAINT `study_fk2` FOREIGN KEY (`profile_id`) REFERENCES `profile` (`profile_id`);
  </code></pre>
  
  <p>Form buidlers are:</p>
  
  <pre><code>class ProfileType extends AbstractType {
  
      public function buildForm(FormBuilder $builder, array $options)
      {
          $builder-&gt;add('study', 'collection', array(
                      'type' =&gt; new StudyType(),
                      'allow_add' =&gt; true,
                      'allow_delete' =&gt; true
                          )
                  )
      }
  ...
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>class StudyType extends AbstractType {
  
      public function buildForm(FormBuilder $builder, array $options)
      {
          $builder
                  -&gt;add('city') //example field not included in above structures
      }
  ...
  }
  </code></pre>
  
  <p>The Javascript part</p>
  
  <pre><code>function profileNewStudy() {
      var nr = $('[class^=profile_study_][class*=type2]').last().parent();
      nr = nr.attr('id').split('_');
      nr = nr.pop()*1 + 1;
      var proto = $('#profile_study').data('prototype');
      proto = proto.replace(/\$\$name\$\$/g, nr);
      $('#profile_study').append(proto).find('.profile_study_' + nr + ' input').val('qpa' + nr);
  }
  </code></pre>
  
  <p>and Twig template</p>
  
  <pre><code>&lt;form action="#" method="post" {{ form_enctype(form) }}&gt;
      {{ form_widget(form) }}
      &lt;input type="submit" value="Zapisz"/&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>For testing purposes I removed from database constraint NOT NULL on study.profile_id and then everything was saved except that study.profile_id=null.</p>
  
  <p><strong>edited after @Gremo answer</strong></p>
  
  <p>I did some tests. Unfortunately it didn't help :( I corrected his mistakes with code</p>
  
  <pre><code>class Profile
      /**
       * @var Study
       * @ORM\OneToMany(targetEntity="Study", mappedBy="profile")
       */
      private $study;
  class Study
      /**
       * @var Profile
       * @ORM\ManyToOne(targetEntity="Profile", inversedBy="study")
       * @ORM\JoinColumn(nullable=false, onDelete="CASCADE", referencedColumnName="profile_id")
       */
      private $profile;
  </code></pre>
  
  <p>and when I added new Study entity in form and posted it to server I got an error: A new entity was found through the relationship 'Alden\xxxBundle\Entity\Profile#study' that was not configured to cascade persist operations for entity: Alden\xxxBundle\Entity\Study@0000000073eb1a8b00000000198469ff. Explicitly persist the new entity or configure cascading persist operations on the relationship. If you cannot find out which entity causes the problem implement 'Alden\xxxxBundle\Entity\Study#__toString()' to get a clue. </p>
  
  <p>So I added cascade to profile:</p>
  
  <pre><code>/**
   * @var Study
   * @ORM\OneToMany(targetEntity="Study", mappedBy="profile", cascade={"persist"})
   */
  private $study;
  </code></pre>
  
  <p>and than I got an error like in the begining: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'profile_id' cannot be null.</p>
  
  <p><strong>edited</strong>
  My controller code:</p>
  
  <pre><code>    $request = $this-&gt;getRequest();
      $r = $this-&gt;getProfileRepository();
      $profile = $id ? $r-&gt;find($id) : new \Alden\BonBundle\Entity\Profile();
      /* @var $profile \Alden\BonBundle\Entity\Profile */
      $form = $this-&gt;createForm(new ProfileType(), $profile);
      if ($request-&gt;getMethod() == 'POST')
      {
          $form-&gt;bindRequest($request);
          if ($form-&gt;isValid())
          {
              $vacation = $profile-&gt;getVacation();
              foreach($vacation as $v) {
                  $r=5;
              }
              $em = $this-&gt;getEntityManager();
              $em-&gt;persist($profile);
              $em-&gt;flush();
              //return $this-&gt;redirect($this-&gt;generateUrl('profile_list'));
          }
      }
      return array(
          'profile' =&gt; $profile,
          'form' =&gt; $form-&gt;createView()
      );
  </code></pre>
  
  <p><strong>SOLUTION</strong></p>
  
  <p>In Profile class, important parts are cascade, orphanRemoval in annotations and foreach loop in setStudies() (thanks to suggestion @Parhs)</p>
  
  <pre><code>/**
   * @var \Doctrine\Common\Collections\ArrayCollection
   * @ORM\OneToMany(targetEntity="Study", mappedBy="profile", cascade={"ALL"}, orphanRemoval=true)
   */
  private $studies;
  
  public function __construct()
  {
      $this-&gt;studies = new \Doctrine\Common\Collections\ArrayCollection();
  }
  
  /**
   * @return Doctrine\Common\Collections\Collection
   */
  public function getStudies()
  {
      return $this-&gt;studies;
  }
  
  public function setStudies($studies)
  {
      foreach ($studies as $v)
      {
          if (is_null($v-&gt;getProfile()))
          {
              $v-&gt;setProfile($this);
          }
      }
      $this-&gt;studies = $studies;
  }
  </code></pre>
  
  <p>In Study class</p>
  
  <pre><code>/**
   * @var Profile
   * @ORM\ManyToOne(targetEntity="Profile", inversedBy="studies")
   * @ORM\JoinColumn(name="profile_id", nullable=false, onDelete="CASCADE", referencedColumnName="profile_id")
   */
  private $profile;
  </code></pre>
  
  <p>and usual getters and setters.</p>