title: Overriding default identifier generation strategy has no effect on associations
body: <p>Symfony 2.7.2. Doctrine ORM 2.4.7. MySQL 5.6.12. PHP 5.5.0.<br>
  I have an entity with custom ID generator strategy. It works flawlessly.<br>
  In some circumstances I have to override this strategy with a "handmade" Id. It works when the main entity is being flushed without associations. But it doesn't work with associations. This example error is thrown:</p>
  
  <blockquote>
    <p>An exception occurred while executing 'INSERT INTO articles_tags (article_id, tag_id) VALUES (?, ?)' with params ["a004r0", 4]:</p>
    
    <p>SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (<code>sf-test1</code>.<code>articles_tags</code>, CONSTRAINT <code>FK_354053617294869C</code> FOREIGN KEY (<code>article_id</code>) REFERENCES <code>article</code> (<code>id</code>) ON DELETE CASCADE)</p>
  </blockquote>
  
  <p>Here's how to reproduce:</p>
  
  <ol>
  <li><a href="http://symfony.com/doc/current/book/installation.html#installing-the-symfony-installer">Install and create a Symfony2 application</a>.</li>
  <li>Edit <code>app/config/parameters.yml</code> with your DB parameters.</li>
  <li><p>Using the example <code>AppBundle</code> namespace, create <code>Article</code> and <code>Tag</code> entities in <code>src/AppBundle/Entity</code> directory.</p>
  
  <pre><code>&lt;?php
  // src/AppBundle/Entity/Article.php
  namespace AppBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  
  /**
   * @ORM\Entity
   * @ORM\Table(name="article")
   */
  class Article
  {
      /**
       * @ORM\Column(type="string")
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="CUSTOM")
       * @ORM\CustomIdGenerator(class="AppBundle\Doctrine\ArticleNumberGenerator")
       */
      protected $id;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      protected $title;
  
      /**
       * @ORM\ManyToMany(targetEntity="Tag", inversedBy="articles" ,cascade={"all"})
       * @ORM\JoinTable(name="articles_tags")
       **/
      private $tags;
  
      public function setId($id)
      {
          $this-&gt;id = $id;
      }
  }
  </code></pre>
  
  
  
  <pre><code>&lt;?php
  // src/AppBundle/Entity/Tag.php
  namespace AppBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Doctrine\Common\Collections\ArrayCollection;
  
  /**
   * @ORM\Entity
   * @ORM\Table(name="tag")
   */
  class Tag
  {
      /**
       * @ORM\Column(type="integer")
       * @ORM\Id
       * @ORM\GeneratedValue
       */
      protected $id;
  
      /**
       * @ORM\Column(type="string", length=255)
       */
      protected $name;
  
      /**
       * @ORM\ManyToMany(targetEntity="Article", mappedBy="tags")
       **/
      private $articles;
  }
  </code></pre></li>
  <li><p>Generate getters and setters for the above entities:</p>
  
  <pre><code>php app/console doctrine:generate:entities AppBundle
  </code></pre></li>
  <li><p>Create <code>ArticleNumberGenerator</code> class in <code>src/AppBundle/Doctrine</code>:</p>
  
  <pre><code>&lt;?php
  // src/AppBundle/Doctrine/ArticleNumberGenerator.php
  namespace AppBundle\Doctrine;
  use Doctrine\ORM\Id\AbstractIdGenerator;
  use Doctrine\ORM\Query\ResultSetMapping;
  
  class ArticleNumberGenerator extends AbstractIdGenerator
  {
      public function generate(\Doctrine\ORM\EntityManager $em, $entity)
      {
          $rsm = new ResultSetMapping();
          $rsm-&gt;addScalarResult('id', 'article', 'string');
          $query = $em-&gt;createNativeQuery('select max(`id`) as id from `article` where `id` like :id_pattern', $rsm);
          $query-&gt;setParameter('id_pattern', 'a___r_');
          $idMax = (int) substr($query-&gt;getSingleScalarResult(), 1, 3);
          $idMax++;
          return 'a' . str_pad($idMax, 3, '0', STR_PAD_LEFT) . 'r0';
      }
  }
  </code></pre></li>
  <li><p>Create database: <code>php app/console doctrine:database:create</code>.</p></li>
  <li>Create tables: <code>php app/console doctrine:schema:create</code>.</li>
  <li><p>Edit the example AppBundle <code>DefaultController</code> located in <code>src\AppBundle\Controller</code>. Replace the content with:</p>
  
  <pre><code>&lt;?php
  // src/AppBundle/Controller/DefaultController.php
  namespace AppBundle\Controller;
  
  use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  use Symfony\Component\HttpFoundation\Request;
  use Symfony\Component\HttpFoundation\Response;
  
  use AppBundle\Entity\Article;
  use AppBundle\Entity\Tag;
  
  class DefaultController extends Controller
  {
      /**
       * @Route("/create-default")
       */
      public function createDefaultAction()
      {
          $tag = new Tag();
          $tag-&gt;setName('Tag ' . rand(1, 99));
  
          $article = new Article();
          $article-&gt;setTitle('Test article ' . rand(1, 999));
          $article-&gt;getTags()-&gt;add($tag);
  
          $em = $this-&gt;getDoctrine()-&gt;getManager();
  
          $em-&gt;getConnection()-&gt;beginTransaction();
          $em-&gt;persist($article);
  
          try {
              $em-&gt;flush();
              $em-&gt;getConnection()-&gt;commit();
          } catch (\RuntimeException $e) {
              $em-&gt;getConnection()-&gt;rollBack();
              throw $e;
          }
  
          return new Response('Created article id ' . $article-&gt;getId() . '.');
      }
  
      /**
       * @Route("/create-handmade/{handmade}")
       */
      public function createHandmadeAction($handmade)
      {
          $tag = new Tag();
          $tag-&gt;setName('Tag ' . rand(1, 99));
  
          $article = new Article();
          $article-&gt;setTitle('Test article ' . rand(1, 999));
          $article-&gt;getTags()-&gt;add($tag);
  
          $em = $this-&gt;getDoctrine()-&gt;getManager();
  
          $em-&gt;getConnection()-&gt;beginTransaction();
          $em-&gt;persist($article);
  
          $metadata = $em-&gt;getClassMetadata(get_class($article));
          $metadata-&gt;setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
          $article-&gt;setId($handmade);
  
          try {
              $em-&gt;flush();
              $em-&gt;getConnection()-&gt;commit();
          } catch (\RuntimeException $e) {
              $em-&gt;getConnection()-&gt;rollBack();
              throw $e;
          }
  
          return new Response('Created article id ' . $article-&gt;getId() . '.');
      }
  }
  </code></pre></li>
  <li><p>Run server: <code>php app/console server:run</code>.</p></li>
  <li><p>Navigate to <a href="http://127.0.0.1:8000/create-default">http://127.0.0.1:8000/create-default</a>. Refresh 2 times to see this message:</p>
  
  <blockquote>
    <p>Created article id a003r0.</p>
  </blockquote></li>
  <li><p>Now, navigate to <a href="http://127.0.0.1:8000/create-handmade/test">http://127.0.0.1:8000/create-handmade/test</a>. The expected result is:</p>
  
  <blockquote>
    <p>Created article id test1.</p>
  </blockquote>
  
  <p>but instead you'll get the error:</p>
  
  <blockquote>
    <p>An exception occurred while executing 'INSERT INTO articles_tags (article_id, tag_id) VALUES (?, ?)' with params ["a004r0", 4]:</p>
    
    <p>SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (<code>sf-test1</code>.<code>articles_tags</code>, CONSTRAINT <code>FK_354053617294869C</code> FOREIGN KEY (<code>article_id</code>) REFERENCES <code>article</code> (<code>id</code>) ON DELETE CASCADE)</p>
  </blockquote>
  
  <p>obviously because article with <code>id</code> "a004r0" does not exist.</p></li>
  </ol>
  
  <p>If I comment-out <code>$article-&gt;getTags()-&gt;add($tag);</code> in <code>createHandmadeAction</code>, it works - the result is:</p>
  
  <blockquote>
    <p>Created article id test.</p>
  </blockquote>
  
  <p>and the database is updated accordingly:</p>
  
  <pre class="lang-none prettyprint-override"><code>id     | title
  -------+----------------
  a001r0 | Test article 204
  a002r0 | Test article 12
  a003r0 | Test article 549
  test   | Test article 723
  </code></pre>
  
  <p>but not when a relationship is added. For a reason, Doctrine does not use the handmade <code>id</code> for associations, instead it uses the default Id generator strategy.</p>
  
  <p>What's wrong here? How to convince the entity manager to use my handmade Ids for associations?</p>