title: Data Transformer for Collection Field Type
body: <p>I am creating a Chat system. I have two entities Chat and ChatThread.</p>
  
  <pre><code>namespace Acme\UitBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  
  /**
  * Chat
  *
  * @ORM\Table()
  * @ORM\Entity(repositoryClass="Acme\UitBundle\Entity\ChatRepository")
  * @ORM\HasLifecycleCallbacks()
  */
  class Chat
  {
  /**
   * @var integer
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;
  
   /**
   * @ORM\ManyToOne(targetEntity="User", inversedBy="chats")
   * @ORM\JoinColumn(name="uid", referencedColumnName="id")
   */
  private $user;
  
  /**
   * @var string
   *
   * @ORM\Column(name="msg", type="text")
   */
  private $msg;
  
  /**
   * @ORM\ManyToOne(targetEntity="ChatThread", inversedBy="chats")
   * @ORM\JoinColumn(name="tid", referencedColumnName="id")
   */
  private $thread;
  
  /**
   * @var \DateTime
   *
   * @ORM\Column(name="date", type="datetime")
   */
  private $date;
  
  /**
   * Get id
   *
   * @return integer 
   */
  public function getId()
  {
      return $this-&gt;id;
  }
  
  /**
   * Set user
   *
   * @param \stdClass $user
   * @return Chat
   */
  public function setUser($user)
  {
      $this-&gt;user = $user;
  
      return $this;
  }
  
  /**
   * Get user
   *
   * @return \stdClass 
   */
  public function getUser()
  {
      return $this-&gt;user;
  }
  
  /**
   * Set msg
   *
   * @param string $msg
   * @return Chat
   */
  public function setMsg($msg)
  {
      $this-&gt;msg = $msg;
  
      return $this;
  }
  
  /**
   * Get msg
   *
   * @return string 
   */
  public function getMsg()
  {
      return $this-&gt;msg;
  }
  
  /**
   * Set date
   *
   * @param \DateTime $date
   * @return Chat
   */
  public function setDate($date)
  {
      $this-&gt;date = $date;
  
      return $this;
  }
  
  /**
   * Get date
   *
   * @return \DateTime 
   */
  public function getDate()
  {
      return $this-&gt;date;
  }
  
  /**
  * @ORM\PrePersist
  */
  public function setDateValue()
  {
  $this-&gt;date = new \DateTime();
  }
  
  
  
  /**
   * Set thread
   *
   * @param \Acme\UitBundle\Entity\ChatThread $thread
   * @return Chat
   */
  public function setThread(\Acme\UitBundle\Entity\ChatThread $thread = null)
  {
      $this-&gt;thread = $thread;
  
      return $this;
  }
  
  /**
   * Get thread
   *
   * @return \Acme\UitBundle\Entity\ChatThread 
   */
  public function getThread()
  {
      return $this-&gt;thread;
  }
  }
  </code></pre>
  
  <p>Entity <strong>ChatThread</strong> :</p>
  
  <pre><code> namespace Acme\UitBundle\Entity;
  
   use Doctrine\ORM\Mapping as ORM;
   use Doctrine\ORM\Mapping\OrderBy;
   use Doctrine\Common\Collections\ArrayCollection;
  
  /**
  * ChatThread
  *
  * @ORM\Table()
  * @ORM\Entity(repositoryClass="Acme\UitBundle\Entity\ChatThreadRepository")
  */
  class ChatThread
  {
  /**
   * @var integer
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;
  
   /**
   * @ORM\ManyToMany(targetEntity="User", inversedBy="inside")
   */
  private $inside;
  
  
  /**
  * @ORM\OneToMany(targetEntity="Chat", mappedBy="thread")
  * @OrderBy({"date" = "DESC"})
  */
  private $chats;
  
  
  public function __construct()
  {
      $this-&gt;chats=new ArrayCollection();
      $this-&gt;inside=new ArrayCollection();
  }
  
  
  /**
   * Get id
   *
   * @return integer 
   */
  public function getId()
  {
      return $this-&gt;id;
  }
  
  /**
   * Set inside
   *
   * @param array $inside
   * @return ChatThread
   */
  public function setInside($inside)
  {
      $this-&gt;inside = $inside;
  
      return $this;
  }
  
  /**
   * Get inside
   *
   * @return array 
   */
  public function getInside()
  {
      return $this-&gt;inside;
  }
  
  /**
   * Add inside
   *
   * @param \Acme\UitBundle\Entity\User $inside
   * @return ChatThread
   */
  public function addInside(\Acme\UitBundle\Entity\User $inside)
  {
      $this-&gt;inside[] = $inside;
  
      return $this;
  }
  
  /**
   * Remove inside
   *
   * @param \Acme\UitBundle\Entity\User $inside
   */
  public function removeInside(\Acme\UitBundle\Entity\User $inside)
  {
      $this-&gt;inside-&gt;removeElement($inside);
  }
  
  /**
   * Add chats
   *
   * @param \Acme\UitBundle\Entity\Chat $chats
   * @return ChatThread
   */
  public function addChat(\Acme\UitBundle\Entity\Chat $chats)
  {
      $this-&gt;chats[] = $chats;
  
      return $this;
  }
  
  /**
   * Remove chats
   *
   * @param \Acme\UitBundle\Entity\Chat $chats
   */
  public function removeChat(\Acme\UitBundle\Entity\Chat $chats)
  {
      $this-&gt;chats-&gt;removeElement($chats);
  }
  
  /**
   * Get chats
   *
   * @return \Doctrine\Common\Collections\Collection 
   */
  public function getChats()
  {
      return $this-&gt;chats;
  }
  }
  </code></pre>
  
  <p>What I want to do is Take users to be added in <strong>inside</strong> and create a ChatThread and add a msg in Chat.
  I have a form of chatType which takes user id's as collection with name thread. I have used a data transformer to transform inside into ChatThread.</p>
  
  <pre><code>namespace Acme\UitBundle\Form\Type;
  use Symfony\Component\Form\AbstractType;
  use Symfony\Component\Form\FormBuilderInterface;
  use Symfony\Component\OptionsResolver\OptionsResolverInterface;
  use Acme\UitBundle\Form\DataTransformer\ThreadToInsideTransformer;
  
  class ChatType extends AbstractType {
  public function buildForm(FormBuilderInterface $builder, array $options) {
      $entityManager = $options['em'];
      $transformer = new ThreadToInsideTransformer($entityManager);
  
      $builder-&gt;add(
              $builder-&gt;create('thread', 'collection' ,array('allow_add'  =&gt; true,'label' =&gt; false))-&gt;addModelTransformer($transformer)
              ); 
      $builder-&gt;add('msg','textarea');
      /* $builder-&gt;add('inside','collection',array(
          'allow_add' =&gt; true,
          'allow_delete' =&gt; true)); */
      $builder-&gt;add('hook', 'submit');
  }
  
  public function setDefaultOptions(OptionsResolverInterface $resolver) {
  $resolver-&gt;setDefaults(array(
  'data_class' =&gt; 'Acme\UitBundle\Entity\Chat'
  ))
          -&gt;setRequired(array(
              'em',
          ))
          -&gt;setAllowedTypes(array(
              'em' =&gt; 'Doctrine\Common\Persistence\ObjectManager',
          ));
  }
  
  public function getName() {
      return 'chat';
  }
  }
  </code></pre>
  
  <p><strong>data transformer</strong></p>
  
  <pre><code>namespace Acme\UitBundle\Form\DataTransformer;
  
  use Symfony\Component\Form\DataTransformerInterface;
  use Symfony\Component\Form\Exception\TransformationFailedException;
  use Doctrine\Common\Persistence\ObjectManager;
  use Acme\UitBundle\Entity\ChatThread;
  
  class ThreadToInsideTransformer implements DataTransformerInterface
  {
  /**
   * @var ObjectManager
   */
  private $om;
  
  /**
   * @param ObjectManager $om
   */
  public function __construct(ObjectManager $om)
  {
      $this-&gt;om = $om;
  }
  
  /**
   * Transforms an object (thread) to an array (inside).
   *
   * @param  Thread $thread
   * @return array
   */
  public function transform($thread)
  {
      if (null === $thread) {
          return "";
      }
  
      return $thread-&gt;getInside();
  }
  
  /**
   * Transforms a array (inside) to an object (thread).
   *
   * @param  array $inside
   *
   * @return Thread
   *
   * @throws Create new Thread if object (thread) is not found.
   */
  public function reverseTransform($inside)
  {
      if (!is_array($inside)) {
          return null;
      }
  
      $a=$this-&gt;om
          -&gt;getRepository('AcmeUitBundle:User')
          -&gt;findById($inside);
  
      if (null === $a) {
          throw new TransformationFailedException(sprintf(
              'Error. . .'
          ));
      }
  
      $thread = $this-&gt;om
          -&gt;getRepository('AcmeUitBundle:ChatThread')
          -&gt;findByInsideChat($a)
      ;
  
      if (null === $thread) {
          $thread=new ChatThread();
                  $thread-&gt;setInside($inside);
                  $this-&gt;om-&gt;persist($thread);
                  $this-&gt;om-&gt;flush();
      }
  
      return $thread;
  }
  }
  </code></pre>
  
  <p>When I submit form, I get this error <strong>Expected argument of type "object, array or empty", "string" given.</strong></p>