title: Symfony2, field type entity, "many-to-many" relation with extra fields, problems with the relation/ArrayCollection/multipe checkboxes in form
body: <p>I want to create a form for a simple entry management.
  I got the entities Entry, EntryUser, and User.
  Tables in database: entry, entry_user and user.</p>
  
  <p>I think i am close to be successful, but i got some problems here.</p>
  
  <p>In my form, the author can check the users he want to add to the entry via checkboxes. Symfony/Doctrine should do the relation work for me and add rows into entry_user. One row for one selected checkbox.</p>
  
  <p>Entry.php</p>
  
  <pre><code>/**
   * @ORM\Entity
   * @ORM\Table(name="entry")
   */
  class Entry {
  
      /**
       * @ORM\Id
       * @ORM\Column(type="integer")
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      protected $id;
  
      /**
       * @ORM\OneToMany(targetEntity="EntryUser", mappedBy="entry", cascade={"all"}, orphanRemoval=true)
       */
     protected $users;
  
      function __construct() {
          $this-&gt;users = new ArrayCollection();
      }
  
      /**
       * Add user
       *
       * @param User $user
       * @return $this
       *
       */
      public function addUser(User $user)
      {
          if (!$this-&gt;users-&gt;contains($user)) {
              $this-&gt;users-&gt;add($user);
          }
  
          return $this;
      }
  
      /**
       * Remove user
       *
       * @param User $user
       * @return $this
       */
      public function removeUser(User $user)
      {
          if ($this-&gt;users-&gt;contains($user)) {
              $this-&gt;users-&gt;removeElement($user);
          }
  
          return $this;
      }
  
      /**
      * @return array
      */
      public function getUsers()
      {
          return $this-&gt;users-&gt;toArray();
      }
  
      /**
      * Returns the true ArrayCollection of Users.
      * @return Doctrine\Common\Collections\ArrayCollection
      */
      public function getUsersCollection()
      {
          return $this-&gt;users;
      }
  
  }
  </code></pre>
  
  <p>User.php</p>
  
  <pre><code>/**
   * @ORM\Entity
   * @ORM\Table(name="user")
   */
  class User implements AdvancedUserInterface, EquatableInterface, \Serializable {
  
      /**
       * @ORM\Id
       * @ORM\Column(type="integer")
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      protected $id;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      protected $name;
  
      /**
       * Get id
       *
       * @return integer
       */
      public function getId()
      {
          return $this-&gt;id;
      }
  
      /**
       * Set name
       *
       * @param string $name
       * @return User
       */
      public function setName($name)
      {
          $this-&gt;name = $name;
  
          return $this;
      }
  
      /**
       * Get name
       *
       * @return string
       */
      public function getName()
      {
          return $this-&gt;name;
      }
  
      // Many other methods for user sign in, roles and so on...
  
  }
  </code></pre>
  
  <p>EntryUser.php</p>
  
  <pre><code>/**
   * @ORM\Entity
   * @ORM\Table(name="entry_user")
   */
  class EntryUser {
  
      /**
       * @var integer
       *
       * @ORM\Column(name="id", type="integer")
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      protected $id;
  
      /**
       * @var integer
       *
       * @ORM\Column(name="user_id", type="integer", nullable=true)
       */
      protected $user_id;
  
      /**
       * @var integer
       *
       * @ORM\Column(name="entry_id", type="integer", nullable=true)
       */
      protected $entry_id;
  
      /**
       * @var User
       *
       * @ORM\ManyToOne(targetEntity="User", cascade={"persist"})
       * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
       */
      protected $user;
  
      /**
       * @var Entry
       *
       * @ORM\ManyToOne(targetEntity="Entry", inversedBy="users")
       * @ORM\JoinColumn(name="entry_id", referencedColumnName="id", onDelete="SET NULL")
       */
      protected $entry;
  
  
      /**
       * Get id
       *
       * @return integer
       */
      public function getId()
      {
          return $this-&gt;id;
      }
  
      /**
       * Set user_id
       *
       * @param integer $userId
       * @return EntryUser
       */
      public function setUserId($userId)
      {
          $this-&gt;user_id = $userId;
  
          return $this;
      }
  
      /**
       * Get user_id
       *
       * @return integer
       */
      public function getUserId()
      {
          return $this-&gt;user_id;
      }
  
      /**
       * Set entry_id
       *
       * @param integer $entryId
       * @return EntryUser
       */
      public function setEntryId($entryId)
      {
          $this-&gt;entry_id = $entryId;
  
          return $this;
      }
  
      /**
       * Get entry_id
       *
       * @return integer
       */
      public function getEntryId()
      {
          return $this-&gt;entry_id;
      }
  
      /**
       * Set user
       *
       * @param User $user
       * @return EntryUser
       */
      public function setUser(User $user = null)
      {
          $this-&gt;user = $user;
  
          return $this;
      }
  
      /**
       * Get user
       *
       * @return User
       */
      public function getUser()
      {
          return $this-&gt;user;
      }
  
      /**
       * Set entry
       *
       * @param Entry $entry
       * @return EntryUser
       */
      public function setEntry(Entry $entry = null)
      {
          $this-&gt;entry = $entry;
  
          return $this;
      }
  
      /**
       * Get entry
       *
       * @return Entry
       */
      public function getEntry()
      {
          return $this-&gt;entry;
      }
  
  }
  </code></pre>
  
  <p>I use ManyToOne relationships here because i want to use a file named EntryUser.php to add some custom fields later. I need this because i must store some additional data there in entry_user.</p>
  
  <p>Because:</p>
  
  <pre><code>And it's the right thing to do. Create a new entity with the new fields, and if you need it, create a custom repository to add the methods you need.
  
  A &lt;--- Many to many with field ---&gt; B
  
  would become
  
  A --One to many--&gt; C (with new fields) &lt;-- One to many--B
  
  and of course, C has ManyToOne relationships with both A and B.
  </code></pre>
  
  <p>See the comments in: <a href="https://stackoverflow.com/questions/15204349/manytomany-relationship-with-extra-fields-in-symfony2-orm-doctrine">ManyToMany relationship with extra fields in symfony2 orm doctrine</a></p>
  
  <p>My EntryType.php form definition includes the following, to create the checkboxes for the template:</p>
  
  <pre><code>$builder-&gt;add('users', 'entity', array(
      'class' =&gt; 'MyCompMyAppBundle:User',
      'multiple' =&gt; true,
      'expanded' =&gt; true,
      'property' =&gt; 'name',
      'label' =&gt; 'Freunde',
      'query_builder' =&gt; function(EntityRepository $er) {
  
          return $er-&gt;createQueryBuilder('u')-&gt;select('a')
              -&gt;from('MyComp\MyAppBundle\Entity\User', 'a')
              -&gt;where('EXISTS (
                  SELECT b
                  FROM MyComp\MyAppBundle\Entity\UserFriend b
                  WHERE b.created_by = :my_user_id
                  AND b.friend_user_id = a.id
              )')
              -&gt;andWhere('EXISTS (
                  SELECT c
                  FROM MyComp\MyAppBundle\Entity\UserFriend c
                  WHERE c.created_by = a.id
                  AND c.friend_user_id = :my_user_id
              )')
             -&gt;setParameter('my_user_id', $this-&gt;user-&gt;getId());
  
      },
      'required' =&gt; true,
  ));
  </code></pre>
  
  <p>As you can see, i load User objects here for the form field (type: entity).
  UserFriend is another entity (table: user_friend). A friend list is saved there. Here all the friends gets loaded. They will be shows as the checkboxes.</p>
  
  <p>Now, if i go to my form in my browser, and check some users for the entry und if i submit the form, i get this error:</p>
  
  <pre><code>ORMException: Found entity of type MyComp\MyAppBundle\Entity\User on association MyComp\MyAppBundle\Entity\Entry#friends, but expecting MyComp\MyAppBundle\Entity\EntryUser
  </code></pre>
  
  <p>So it is very confusing.
  How can i make this work?</p>
  
  <p>How can i make symfony and doctrine work to insert data automatically into entry and entry_user?</p>
  
  <p>Important: I want to make it possible that the author can edit the entry later. So the checkboxes should be selected by default as it is saved in entry_user.</p>
  
  <p>I just try to understand this and got a little bit confused. But i dont know how to make this work. </p>