title: How to setup a data transformer in Symfony to reuse existing entities?
body: <p>I'm working on an article editor in Symfony with built-in tagging capability:</p>
  
  <p><img src="https://i.stack.imgur.com/HasKr.png" alt="You can add tags from inside the article form."> </p>
  
  <h1>The controller</h1>
  
  <pre><code>class MainController extends Controller
  {
      public function indexAction(Request $request, $id)
      {
          $em = $this-&gt;getDoctrine()-&gt;getManager();
  
          // $article = ...
  
          $form = $this-&gt;createForm(new ArticleType(), $article);
          $form-&gt;handleRequest($request);
  
          if ($form-&gt;isValid()) {
              $em-&gt;persist($article);
              $em-&gt;flush();
              return $this-&gt;redirect($this-&gt;generateUrl('acme_edit_success'));
          }
  
          return $this-&gt;render('AcmeBundle:Main:index.html.twig', array(
              'form' =&gt; $form-&gt;createView()
          ));
  
      }
  }
  </code></pre>
  
  <h1>The forms</h1>
  
  <p>The tag form is registered as a service with the <code>@Doctrine</code> argument, so I can use the entity manager inside the class. The tag form is embed inside the article form.</p>
  
  <h2>ArticleType.php</h2>
  
  <pre><code>class ArticleType extends AbstractType
  {
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $builder
              -&gt;add('content')
              -&gt;add('tags', 'collection', array(
                  'type' =&gt; 'acme_bundle_tagtype',
                  'allow_add' =&gt; true,
                  'allow_delete' =&gt; true,
                  'by_reference' =&gt; false
              ))
              -&gt;add('save', 'submit')
          ;
      }
  
      public function setDefaultOptions(OptionsResolverInterface $resolver)
      {
          $resolver-&gt;setDefaults(array(
              'data_class' =&gt; 'Acme\Bundle\Entity\Article',
              'cascade_validation' =&gt; true
          ));
      }
  
      public function getName()
      {
          return 'acme_bundle_articletype';
      }
  }
  </code></pre>
  
  <h2>TagType.php</h2>
  
  <pre><code>class TagType extends AbstractType
  {
      private $entityManager;
  
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $transformer = new TagTransformer($this-&gt;entityManager);
  
          $builder-&gt;add(
              $builder-&gt;create('name')
                  -&gt;addModelTransformer($transformer)
          );
      }
  
      function __construct(\Doctrine\Bundle\DoctrineBundle\Registry $doctrine) {
          $this-&gt;entityManager = $doctrine-&gt;getManager();
      }
  
      public function setDefaultOptions(OptionsResolverInterface $resolver)
      {
          $resolver-&gt;setDefaults(array(
              'data_class' =&gt; 'Acme\Bundle\Entity\Tag'
          ));
      }
  
      public function getName()
      {
          return 'acme_bundle_tagtype';
      }
  }
  </code></pre>
  
  <h1>The data transformer</h1>
  
  <p>I created this data transformer to check if the given tag already exists and then transform the tag object to the one that already exists in the database:</p>
  
  <pre><code>class TagTransformer implements DataTransformerInterface
  {
      /**
       * @var ObjectManager
       */
      private $om;
  
      /**
       * @param ObjectManager $om
       */
      public function __construct(ObjectManager $om)
      {
          $this-&gt;om = $om;
      }
  
      public function transform($tag)
      {
          if (null === $tag) {
              return '';
          }
  
          return $tag;
      }
  
      public function reverseTransform($name)
      {
          if (!$name)
              return null;
  
          $tag = $this-&gt;om
              -&gt;getRepository('AcmeBundle:Tag')
              -&gt;findOneByName($name)
          ;
  
          if (!$tag) {
              $tag = new Tag();
              $tag-&gt;setName($name);
          }
  
          return $tag;
      }
  }
  </code></pre>
  
  <p>When I try to save an article with an already existing tag, the <code>reverseTransform()</code> function successfully returns the original tag objects, but <strong>the DBAL converts the object back to a string by its <code>__toString()</code> method</strong>, and Doctrine still initiates an <code>INSERT</code> query instead of <code>UPDATE</code>, so I get the next error:</p>
  
  <blockquote>
    <p>An exception occurred while executing 'INSERT INTO Tag (name)
    VALUES (?)' with params [{}]:</p>
    
    <p>SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry
    'An Existing Tag' for key 'UNIQ_0123456789ABCDE'</p>
  </blockquote>
  
  <p>How can I fix this? When I enter a tag name that's already in use, I want Symfony to use the same tag in the article-tag relationship. The entity classes appear in my previous question about <a href="https://stackoverflow.com/q/21712710">how to avoid duplicate entries in a many-to-many relationship with Doctrine</a>.</p>