title: Symfony2 After form submit got string instead entity
body: <p>I have some error:</p>
  
  <blockquote>
    <p>Expected value of type "AdBundle\Entity\AdLocation" for association
    field "AdBundle\Entity\AdBase#$location", got "string" instead.</p>
  </blockquote>
  
  <p>Does I need to use DataTransformer? Why I cant use only EntityType field without other manipulations?</p>
  
  <p>AdBase entity:</p>
  
  <pre><code>&lt;?php
  
  namespace AdBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Symfony\Component\Validator\Constraints as Assert;
  
  /**
   * AdBase
   *
   * @ORM\Table(name="ad_base")
   * @ORM\Entity(repositoryClass="AdBundle\Repository\AdBaseRepository")
   * @ORM\HasLifecycleCallbacks()
   * @ORM\InheritanceType("JOINED")
   * @ORM\DiscriminatorColumn(name="discr", type="string")
   * @ORM\DiscriminatorMap({
      "flat" = "AdFlat"
   *     })
   */
  abstract class AdBase
  {
      /**
       * @var int
       *
       * @ORM\Column(name="id", type="integer")
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      protected $id;
  
      /**
       * @var string
       *
       * @ORM\Column(name="author", type="string", length=255)
       */
      private $author;
  
      /**
       * @ORM\ManyToOne(targetEntity="AdBundle\Entity\AdCategory")
       */
      private $category;
  
      /**
       * @ORM\ManyToOne(targetEntity="AdBundle\Entity\AdLocation")
       */
      private $location;
  
      /**
       * @var string
       *
       * @ORM\Column(name="title", type="string", length=255)
       * @Assert\NotBlank(message="Not specified Title")
       */
      private $title;
  
      /**
       * @var string
       *
       * @ORM\Column(name="description", type="text", nullable=true)
       * @Assert\NotBlank(message="Not specified Description")
       */
      private $description;
  
      /**
       * @ORM\OneToMany(targetEntity="AdBundle\Entity\AdPhoto", mappedBy="ad")
       */
      private $photos;
  
      /**
       * @ORM\Column(type="float")
       * @Assert\NotBlank()
       */
      private $price;
  
      /**
       * @ORM\ManyToOne(targetEntity="AdBundle\Entity\AdPriceType")
       */
      private $priceType;
  
      /**
       * @var \DateTime
       *
       * @ORM\Column(name="createdAt", type="datetime")
       */
      private $createdAt;
  
      /**
       * @var string
       *
       * @ORM\Column(name="updatedAt", type="datetime")
       */
      private $updatedAt;
  
      /**
       * @var bool
       *
       * @ORM\Column(name="visible", type="boolean")
       */
      private $visible = false;
  
      /**
       * @ORM\Column(type="boolean")
       */
      private $active = true;
  
  
      /**
       * Set id
       *
       * @param integer $id
       *
       * @return $this
       */
      public function setId($id)
      {
          $this-&gt;id = $id;
  
          return $this;
      }
      /**
       * Get id
       *
       * @return int
       */
      public function getId()
      {
          return $this-&gt;id;
      }
  
      /**
       * Set author
       *
       * @param string $author
       *
       * @return AdBase
       */
      public function setAuthor($author)
      {
          $this-&gt;author = $author;
  
          return $this;
      }
  
      /**
       * Get author
       *
       * @return string
       */
      public function getAuthor()
      {
          return $this-&gt;author;
      }
  
      /**
       * @return mixed
       */
      public function getCategory()
      {
          return $this-&gt;category;
      }
  
      /**
       * @param mixed $category
       */
      public function setCategory($category)
      {
          $this-&gt;category = $category;
      }
  
      /**
       * @return mixed
       */
      public function getLocation()
      {
          return $this-&gt;location;
      }
  
      /**
       * @param mixed $location
       */
      public function setLocation($location)
      {
          $this-&gt;location = $location;
      }
  
      /**
       * Set title
       *
       * @param string $title
       *
       * @return AdBase
       */
      public function setTitle($title)
      {
          $this-&gt;title = $title;
  
          return $this;
      }
  
      /**
       * Get title
       *
       * @return string
       */
      public function getTitle()
      {
          return $this-&gt;title;
      }
  
      /**
       * Set description
       *
       * @param string $description
       *
       * @return AdBase
       */
      public function setDescription($description)
      {
          $this-&gt;description = $description;
  
          return $this;
      }
  
      /**
       * Get description
       *
       * @return string
       */
      public function getDescription()
      {
          return $this-&gt;description;
      }
  
      /**
       * Set photos
       *
       * @param string $photos
       *
       * @return AdBase
       */
      public function setPhotos($photos)
      {
          $this-&gt;photos = $photos;
  
          return $this;
      }
  
      /**
       * Get photos
       *
       * @return string
       */
      public function getPhotos()
      {
          return $this-&gt;photos;
      }
  
      /**
       * @return mixed
       */
      public function getPrice()
      {
          return $this-&gt;price;
      }
  
      /**
       * @param mixed $price
       */
      public function setPrice($price)
      {
          $this-&gt;price = $price;
      }
  
      /**
       * @return mixed
       */
      public function getPriceType()
      {
          return $this-&gt;priceType;
      }
  
      /**
       * @param mixed $priceType
       */
      public function setPriceType($priceType)
      {
          $this-&gt;priceType = $priceType;
      }
  
      /**
       * Set createdAt
       *
       * @param \DateTime $createdAt
       *
       * @return AdBase
       */
      public function setCreatedAt($createdAt)
      {
          $this-&gt;createdAt = $createdAt;
  
          return $this;
      }
  
      /**
       * Get createdAt
       *
       * @return \DateTime
       */
      public function getCreatedAt()
      {
          return $this-&gt;createdAt;
      }
  
      /**
       * Set updatedAt
       *
       * @param string $updatedAt
       *
       * @return AdBase
       */
      public function setUpdatedAt($updatedAt)
      {
          $this-&gt;updatedAt = $updatedAt;
  
          return $this;
      }
  
      /**
       * Get updatedAt
       *
       * @return string
       */
      public function getUpdatedAt()
      {
          return $this-&gt;updatedAt;
      }
  
      /**
       * Set visible
       *
       * @param boolean $visible
       *
       * @return AdBase
       */
      public function setVisible($visible)
      {
          $this-&gt;visible = $visible;
  
          return $this;
      }
  
      /**
       * Get visible
       *
       * @return bool
       */
      public function getVisible()
      {
          return $this-&gt;visible;
      }
  
      /**
       * @return mixed
       */
      public function getActive()
      {
          return $this-&gt;active;
      }
  
      /**
       * @param mixed $active
       */
      public function setActive($active)
      {
          $this-&gt;active = $active;
      }
  
      /**
       * @ORM\PrePersist()
       */
      public function prePersist()
      {
          $this-&gt;author = 'voodoo';
          $this-&gt;createdAt = new \DateTime('now', new \DateTimeZone('UTC'));
          $this-&gt;updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
          $this-&gt;location = 'Donetsk';
      }
  
      /**
       * @ORM\PreUpdate()
       */
      public function preUpdate()
      {
          $this-&gt;updatedAt = new \DateTime('now', new \DateTimeZone('UTC'));
      }
  }
  </code></pre>
  
  <p>AdFlat entity:</p>
  
  <pre><code>&lt;?php
  
  namespace AdBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Symfony\Component\Validator\Constraints as Assert;
  
  /**
   * AdFlat
   *
   * @ORM\Table(name="ad_flat")
   * @ORM\Entity(repositoryClass="AdBundle\Repository\AdFlatRepository")
   */
  class AdFlat extends AdBase
  {
      /**
       * @var integer
       *
       * @ORM\Column(type="integer")
       * @Assert\NotBlank(message="ad_flat.rooms.not_blank")
       */
      private $rooms;
  
      /**
       * @var float
       *
       * @ORM\Column(name="square", type="float", nullable=true)
       */
      private $square;
  
      /**
       * @var float
       *
       * @ORM\Column(name="liveSquare", type="float", nullable=true)
       */
      private $liveSquare;
  
      /**
       * @var float
       *
       * @ORM\Column(type="float", nullable=true)
       */
      private $kitchenSquare;
  
      /**
       * @var int
       *
       * @ORM\Column(name="floor", type="integer")
       */
      private $floor;
  
      /**
       * @var int
       *
       * @ORM\Column(name="floors", type="integer")
       */
      private $floors;
  
      /**
       * @var string
       *
       * @ORM\ManyToOne(targetEntity="AdBundle\Entity\AdWallType")
       */
      private $wallType;
  
      /**
       * @ORM\ManyToOne(targetEntity="AdBundle\Entity\AdWCType")
       */
      private $wcType;
  
      /**
       * @return mixed
       */
      public function getRooms()
      {
          return $this-&gt;rooms;
      }
  
      /**
       * @param mixed $rooms
       */
      public function setRooms($rooms)
      {
          $this-&gt;rooms = $rooms;
      }
  
      /**
       * Set square
       *
       * @param float $square
       *
       * @return AdFlat
       */
      public function setSquare($square)
      {
          $this-&gt;square = $square;
  
          return $this;
      }
  
      /**
       * Get square
       *
       * @return float
       */
      public function getSquare()
      {
          return $this-&gt;square;
      }
  
      /**
       * Set liveSquare
       *
       * @param float $liveSquare
       *
       * @return AdFlat
       */
      public function setLiveSquare($liveSquare)
      {
          $this-&gt;liveSquare = $liveSquare;
  
          return $this;
      }
  
      /**
       * Get liveSquare
       *
       * @return float
       */
      public function getLiveSquare()
      {
          return $this-&gt;liveSquare;
      }
  
      /**
       * @return float
       */
      public function getKitchenSquare()
      {
          return $this-&gt;kitchenSquare;
      }
  
      /**
       * @param float $kitchenSquare
       */
      public function setKitchenSquare($kitchenSquare)
      {
          $this-&gt;kitchenSquare = $kitchenSquare;
      }
  
      /**
       * Set floor
       *
       * @param integer $floor
       *
       * @return AdFlat
       */
      public function setFloor($floor)
      {
          $this-&gt;floor = $floor;
  
          return $this;
      }
  
      /**
       * Get floor
       *
       * @return int
       */
      public function getFloor()
      {
          return $this-&gt;floor;
      }
  
      /**
       * Set floors
       *
       * @param integer $floors
       *
       * @return AdFlat
       */
      public function setFloors($floors)
      {
          $this-&gt;floors = $floors;
  
          return $this;
      }
  
      /**
       * Get floors
       *
       * @return int
       */
      public function getFloors()
      {
          return $this-&gt;floors;
      }
  
      /**
       * Set wallType
       *
       * @param string $wallType
       *
       * @return AdFlat
       */
      public function setWallType($wallType)
      {
          $this-&gt;wallType = $wallType;
  
          return $this;
      }
  
      /**
       * Get wallType
       *
       * @return string
       */
      public function getWallType()
      {
          return $this-&gt;wallType;
      }
  
      /**
       * Set wcType
       *
       * @param string $wcType
       *
       * @return AdFlat
       */
      public function setWcType($wcType)
      {
          $this-&gt;wcType = $wcType;
  
          return $this;
      }
  
      /**
       * Get wcType
       *
       * @return string
       */
      public function getWcType()
      {
          return $this-&gt;wcType;
      }
  }
  </code></pre>
  
  <p>AdLocation entity:</p>
  
  <pre><code>&lt;?php
  
  namespace AdBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  
  /**
   * AdLocation
   *
   * @ORM\Table(name="ad_location")
   * @ORM\Entity(repositoryClass="AdBundle\Repository\AdLocationRepository")
   * @ORM\HasLifecycleCallbacks()
   */
  class AdLocation
  {
      /**
       * @var int
       *
       * @ORM\Column(name="id", type="integer")
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       */
      private $id;
  
      /**
       * @ORM\OneToMany(targetEntity="AdBundle\Entity\AdLocation", mappedBy="parent")
       */
      private $children = null;
  
      /**
       * @ORM\ManyToOne(targetEntity="AdBundle\Entity\AdLocation", inversedBy="children")
       * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
       */
      private $parent = null;
  
  
      /**
       * @ORM\Column(type="integer")
       */
      private $level = 0;
  
      /**
       * @var string
       *
       * @ORM\Column(name="title", type="string", length=255)
       */
      private $title;
  
  
      /**
       * @ORM\Column(type="string")
       */
      private $locationType;
  
  
      /**
       * @ORM\Column(type="integer")
       */
      private $weight = 0;
  
      /**
       * @var bool
       *
       * @ORM\Column(name="visible", type="boolean")
       */
      private $visible = true;
  
      /**
       * Get id
       *
       * @return int
       */
      public function getId()
      {
          return $this-&gt;id;
      }
  
      /**
       * Set children
       *
       * @param string $children
       *
       * @return AdLocation
       */
      public function setChildren($children)
      {
          $this-&gt;children = $children;
  
          return $this;
      }
  
      /**
       * Get children
       *
       * @return string
       */
      public function getChildren()
      {
          return $this-&gt;children;
      }
  
      /**
       * Set parent
       *
       * @param string $parent
       *
       * @return AdLocation
       */
      public function setParent($parent)
      {
          $this-&gt;parent = $parent;
  
          return $this;
      }
  
      /**
       * Get parent
       *
       * @return string
       */
      public function getParent()
      {
          return $this-&gt;parent;
      }
  
      /**
       * @return mixed
       */
      public function getLevel()
      {
          return $this-&gt;level;
      }
  
      /**
       * @param mixed $level
       */
      public function setLevel($level)
      {
          $this-&gt;level = $level;
      }
  
      /**
       * Set title
       *
       * @param string $title
       *
       * @return AdLocation
       */
      public function setTitle($title)
      {
          $this-&gt;title = $title;
  
          return $this;
      }
  
      /**
       * Get title
       *
       * @return string
       */
      public function getTitle()
      {
          return $this-&gt;title;
      }
  
      /**
       * @return mixed
       */
      public function getLocationType()
      {
          return $this-&gt;locationType;
      }
  
      /**
       * @param mixed $locationType
       */
      public function setLocationType($locationType)
      {
          $this-&gt;locationType = $locationType;
      }
  
      /**
       * @return mixed
       */
      public function getWeight()
      {
          return $this-&gt;weight;
      }
  
      /**
       * @param mixed $weight
       */
      public function setWeight($weight)
      {
          $this-&gt;weight = $weight;
      }
  
      /**
       * Set visible
       *
       * @param boolean $visible
       *
       * @return AdLocation
       */
      public function setVisible($visible)
      {
          $this-&gt;visible = $visible;
  
          return $this;
      }
  
      /**
       * Get visible
       *
       * @return bool
       */
      public function getVisible()
      {
          return $this-&gt;visible;
      }
  
      /**
       * @ORM\PrePersist()
       */
      public function prePersist()
      {
          if (null !== $this-&gt;getParent()) {
              $this-&gt;setLevel($this-&gt;getParent()-&gt;getLevel() + 1);
          }
      }
  }
  </code></pre>
  
  <p>In controller:</p>
  
  <pre><code>public function addAction(Request $request)
      {
          $categoryId = $request-&gt;get('category_id');
  
          if (!$categoryId) {
              return $this-&gt;renderError('Unknown Ad Category');
          }
  
          $category = $this-&gt;getDoctrine()-&gt;getRepository('AdBundle:AdCategory')-&gt;find($categoryId);
  
          if (null === $category) {
              return $this-&gt;renderError('You cannot create Ad for this category');
          }
  
          if (null === $category-&gt;getEntity()) {
              return $this-&gt;renderError('You cannot create Ad for category ' . $category-&gt;getTitle());
          }
  
          $adEntity = $this-&gt;getEntity($category-&gt;getEntity());
          $adForm = $this-&gt;getForm($category-&gt;getEntity());
  
          $form = $this-&gt;createForm($adForm, $adEntity);
          $form-&gt;handleRequest($request);
  
          if ($form-&gt;isValid()) {
              $em = $this-&gt;getDoctrine()-&gt;getManager();
  
              $photosDir = $this-&gt;getParameter('dir_ad_photo');
  
              foreach ($form['photos']-&gt;getData() as $photo) {
                  $adPhoto = new AdPhoto($photo, $this-&gt;get('kernel')-&gt;getRootDir() . '/../' . $photosDir);
                  $adPhoto-&gt;upload();
                  $adPhoto-&gt;setAd($adEntity);
                  $em-&gt;persist($adPhoto);
              }
  
              $adEntity-&gt;setCategory($category);
  
              $em-&gt;persist($adEntity);
              $em-&gt;flush();
  
              return $this-&gt;redirectToRoute('ad_bundle_ad_view', array(
                  'id' =&gt; $adEntity-&gt;getId()
              ));
          }
  
          return $this-&gt;render('AdBundle:Ad:add-ad-flat.html.twig', array(
              'form' =&gt; $form-&gt;createView(),
              'adType' =&gt; $category-&gt;getTitle()
          ));
      }
  
  private function getEntity($className)
      {
          $entityName = 'AdBundle\Entity\\' . $className;
  
          return new $entityName();
      }
  
      private function getForm($className)
      {
          $formName = 'AdBundle\Form\Type\\' . $className . 'Type';
  
          return new $formName();
      }
  </code></pre>