title: How can I hydrate multiple entities on Doctrine2 QueryBuilder
body: <p>I have a symfony2 application using Doctrine2, and some entities for City, State, Country, Address.</p>
  
  <p>The problem is that if I do this:</p>
  
  
  
  <pre class="lang-php prettyprint-override"><code>    $queryBuilder = $this-&gt;em-&gt;createQueryBuilder();
      $queryBuilder
          -&gt;select(array('country', 'state', 'city', 'address'))
          -&gt;from('CouponiacsMainBundle:Country', 'country')
          -&gt;leftJoin('country.states', 'state', 'WITH', 'state.name=:stateName OR state.shortName=:stateShortName')
          -&gt;leftJoin('state.cities', 'city', 'WITH', 'city.name=:cityName')
          -&gt;leftJoin('city.addresses', 'address', 'WITH', 'address.address=:address AND address.zip=:zip AND address.latitude=:latitude AND address.longitude=:longitude')
          -&gt;where('country.name=:countryName OR country.shortName=:countryShortName')
          -&gt;orderBy('city.name', 'DESC')
          -&gt;setParameters(array(
              'countryName' =&gt; $country,
              'countryShortName' =&gt; $countryShort,
              'stateName' =&gt; $state,
              'stateShortName' =&gt; $stateShort,
              'cityName' =&gt; $city,
              'address' =&gt; $address['address'],
              'zip' =&gt; $address['zip'],
              'latitude' =&gt; $address['latitude'],
              'longitude' =&gt; $address['longitude'],
          ))
          -&gt;setMaxResults(1);
  </code></pre>
  
  <p>the resultset contains only the Country entity, but no State entity. I have also tried the same query using DQL with no success:</p>
  
  <pre class="lang-php prettyprint-override"><code>$query = $this-&gt;em-&gt;createQuery('SELECT country, state, city, address
          FROM CouponiacsMainBundle:Country country
          LEFT JOIN country.states state WITH state.name=:stateName OR state.shortName=:stateShortName
          LEFT JOIN state.cities city WITH city.name=:cityName
          LEFT JOIN city.addresses address WITH address.address=:address AND address.zip=:zip AND address.latitude=:latitude AND address.longitude=:longitude
          WHERE country.name=:countryName OR country.shortName=:countryShortName
          ORDER BY city.name DESC
      ')-&gt;setParameters(array(
          'countryName' =&gt; $country,
          'countryShortName' =&gt; $countryShort,
          'stateName' =&gt; $state,
          'stateShortName' =&gt; $stateShort,
          'cityName' =&gt; $city,
          'address' =&gt; $address['address'],
          'zip' =&gt; $address['zip'],
          'latitude' =&gt; $address['latitude'],
          'longitude' =&gt; $address['longitude'],
      ));
  </code></pre>
  
  <p>If I manually run the generated SQL, the result for state is ok, but on the resultset there is no entity for state. The result is an array with Country entity, and if I do getStates() I get no states.</p>
  
  <p>Any suggestions are appreciated,
  Thanks!</p>
  
  <p><strong>EDIT</strong>:
  Here is the doctrine mapping:</p>
  
  <p>Address entity:</p>
  
  <pre class="lang-php prettyprint-override"><code>    &lt;?php
  
  namespace Couponiacs\MainBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Doctrine\Common\Collections\ArrayCollection;
  use Gedmo\Mapping\Annotation as Gedmo;
  use Gedmo\Timestampable\Traits\TimestampableEntity;
  use Symfony\Component\Validator\Constraints as Assert;
  use Couponiacs\MainBundle\Entity\Traits\EnabledEntity;
  
  /**
  * Address
  *
  * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(name="idx", columns={"city_id", "address", "zip", "latitude", "longitude"})})
  * @ORM\Entity(repositoryClass="Couponiacs\MainBundle\Entity\AddressRepository")
  */
  class Address
  {
      use TimestampableEntity;
      use EnabledEntity;
  
      /**
      * @var integer
      *
      * @ORM\Column(type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
      */
      private $id;
  
      /**
      * @var string
      *
      * @ORM\Column(type="string", length=190)
      */
      private $address = '';
  
      /**
      * @var City $city
      *
      * @ORM\ManyToOne(targetEntity="City", inversedBy="addresses", cascade={"all"})
      */
      private $city;
  
      /**
      * @var string
      *
      * @ORM\Column(type="string", length=16)
      */
      private $zip = '';
  
      /**
      * @var string
      *
      * @ORM\Column(type="string", length=32)
      */
      private $latitude = '';
  
      /**
      * @var string
      *
      * @ORM\Column(type="string", length=32)
      */
      private $longitude = '';
  
      /**
      * @var ArrayCollection $coupons
      *
      * @ORM\ManyToMany(targetEntity="Coupon", mappedBy="addresses", fetch="EXTRA_LAZY", cascade={"all"})
      */
      private $coupons;
  
  
  
      public function __construct()
      {
      $this-&gt;coupons = new ArrayCollection();
      }
  
      /**
      * Get id
      *
      * @return integer 
      */
      public function getId()
      {
      return $this-&gt;id;
      }
  
      /**
      * Set address
      *
      * @param string $address
      * @return Address
      */
      public function setAddress($address)
      {
      $this-&gt;address = $address;
  
      return $this;
      }
  
      /**
      * Get address
      *
      * @return string 
      */
      public function getAddress()
      {
      return $this-&gt;address;
      }
  
      /**
      * Set zip
      *
      * @param string $zip
      * @return Coupon
      */
      public function setZip($zip)
      {
      $this-&gt;zip = $zip;
  
      return $this;
      }
  
      /**
      * Get zip
      *
      * @return string 
      */
      public function getZip()
      {
      return $this-&gt;zip;
      }
  
      /**
      * Set latitude
      *
      * @param string $latitude
      * @return Coupon
      */
      public function setLatitude($latitude)
      {
      $this-&gt;latitude = $latitude;
  
      return $this;
      }
  
      /**
      * Get latitude
      *
      * @return string 
      */
      public function getLatitude()
      {
      return $this-&gt;latitude;
      }
  
      /**
      * Set longitude
      *
      * @param string $longitude
      * @return Coupon
      */
      public function setLongitude($longitude)
      {
      $this-&gt;longitude = $longitude;
  
      return $this;
      }
  
      /**
      * Get longitude
      *
      * @return string 
      */
      public function getLongitude()
      {
      return $this-&gt;longitude;
      }
  
      /**
      * Set city
      *
      * @param \Couponiacs\MainBundle\Entity\City $city
      * @return Address
      */
      public function setCity(City $city = null)
      {
      $this-&gt;city = $city;
  
      return $this;
      }
  
      /**
      * Get city
      *
      * @return \Couponiacs\MainBundle\Entity\City 
      */
      public function getCity()
      {
      return $this-&gt;city;
      }
  
      /**
      * Add coupon
      *
      * @param \Couponiacs\MainBundle\Entity\Coupon $coupon
      * @return Address
      */
      public function addCoupon(Coupon $coupon)
      {
      $this-&gt;coupons[] = $coupon;
  
      return $this;
      }
  
      /**
      * Remove coupon
      *
      * @param \Couponiacs\MainBundle\Entity\Coupon $coupon
      */
      public function removeCoupon(Coupon $coupon)
      {
      $this-&gt;coupons-&gt;removeElement($coupon);
      }
  
      /**
      * Get coupons
      *
      * @return \Doctrine\Common\Collections\Collection
      */
      public function getCoupon()
      {
      return $this-&gt;coupons;
      }
  }
  </code></pre>
  
  <p>City entity:</p>
  
  <pre class="lang-php prettyprint-override"><code>    &lt;?php
  
  namespace Couponiacs\MainBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Doctrine\Common\Collections\ArrayCollection;
  use Gedmo\Mapping\Annotation as Gedmo;
  use Gedmo\Timestampable\Traits\TimestampableEntity;
  use Symfony\Component\Validator\Constraints as Assert;
  use Couponiacs\MainBundle\Entity\Traits\NameEntity;
  use Couponiacs\MainBundle\Entity\Traits\EnabledEntity;
  
  /**
  * City
  *
  * @ORM\Table(
  *   indexes={
  *     @ORM\Index(name="idx_name", columns={"name"})
  *   },
  *   uniqueConstraints={
  *     @ORM\UniqueConstraint(name="idx_state_name", columns={"state_id", "name"})
  *   }
  * )
  * @ORM\Entity(repositoryClass="Couponiacs\MainBundle\Entity\CityRepository")
  */
  class City
  {
      use TimestampableEntity;
      use NameEntity;
      use EnabledEntity;
  
      /**
      * @var integer
      *
      * @ORM\Column(type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
      */
      private $id;
  
      /**
      * @var string
      *
      * @Gedmo\Slug(handlers={
      *   @Gedmo\SlugHandler(class="Gedmo\Sluggable\Handler\RelativeSlugHandler", options={
      *     @Gedmo\SlugHandlerOption(name="relationField", value="state"),
      *     @Gedmo\SlugHandlerOption(name="relationSlugField", value="slug")
      *   })
      * }, fields={"name"})
      * @ORM\Column(type="string", length=190, unique=true)
      * @Assert\NotBlank(message="err.constraint.empty_value")
      */
      private $slug;
  
      /**
      * @var State
      *
      * @ORM\ManyToOne(targetEntity="State", inversedBy="cities", cascade={"all"})
      */
      private $state;
  
      /**
      * @var ArrayCollection $addresses
      *
      * @ORM\OneToMany(targetEntity="Address", mappedBy="city", fetch="EXTRA_LAZY", cascade={"all"})
      */
      private $addresses;
  
  
  
      public function __construct()
      {
      $this-&gt;addresses = new ArrayCollection();
      }
  
      /**
      * Get id
      *
      * @return integer 
      */
      public function getId()
      {
      return $this-&gt;id;
      }
  
      /**
      * Set slug
      *
      * @param string $slug
      * @return City
      */
      public function setSlug($slug)
      {
      $this-&gt;slug = $slug;
  
      return $this;
      }
  
      /**
      * Get slug
      *
      * @return string 
      */
      public function getSlug()
      {
      return $this-&gt;slug;
      }
  
      /**
      * Set state
      *
      * @param \Couponiacs\MainBundle\Entity\State $state
      * @return City
      */
      public function setState(State $state = null)
      {
      $this-&gt;state = $state;
  
      return $this;
      }
  
      /**
      * Get state
      *
      * @return \Couponiacs\MainBundle\Entity\State 
      */
      public function getState()
      {
      return $this-&gt;state;
      }
  
      /**
      * Add address
      *
      * @param \Couponiacs\MainBundle\Entity\Address $address
      * @return City
      */
      public function addAddress(Address $address)
      {
      $this-&gt;addresses[] = $address;
  
      return $this;
      }
  
      /**
      * Remove address
      *
      * @param \Couponiacs\MainBundle\Entity\Address $address
      */
      public function removeAddress(Address $address)
      {
      $this-&gt;addresses-&gt;removeElement($address);
      }
  
      /**
      * Get addresses
      *
      * @return \Doctrine\Common\Collections\Collection 
      */
      public function getAddresses()
      {
      return $this-&gt;addresses;
      }
  }
  </code></pre>
  
  <p>State entity:</p>
  
  <pre class="lang-php prettyprint-override"><code>    &lt;?php
  
  namespace Couponiacs\MainBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Doctrine\Common\Collections\ArrayCollection;
  use Gedmo\Mapping\Annotation as Gedmo;
  use Gedmo\Timestampable\Traits\TimestampableEntity;
  use Symfony\Component\Validator\Constraints as Assert;
  use Couponiacs\MainBundle\Entity\Traits\NameEntity;
  use Couponiacs\MainBundle\Entity\Traits\EnabledEntity;
  
  /**
  * State
  *
  * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(name="idx_name_country", columns={"name", "country_id"})})
  * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(name="idx_shortName_country", columns={"shortName", "country_id"})})
  * @ORM\Entity(repositoryClass="Couponiacs\MainBundle\Entity\StateRepository")
  */
  class State
  {
      use TimestampableEntity;
      use NameEntity;
      use EnabledEntity;
  
      /**
      * @var integer
      *
      * @ORM\Column(type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
      */
      private $id;
  
      /**
      * @var string
      *
      * @ORM\Column(type="string", length=16)
      * @Assert\NotBlank(message="err.constraint.empty_value")
      */
      private $shortName = '';
  
      /**
      * @var string
      *
      * @Gedmo\Slug(handlers={
      *   @Gedmo\SlugHandler(class="Couponiacs\MainBundle\Entity\Handler\RelativeSlugHandler", options={
      *     @Gedmo\SlugHandlerOption(name="relationField", value="country"),
      *     @Gedmo\SlugHandlerOption(name="relationSlugField", value="slug")
      *   })
      * }, fields={"name"})
      * @ORM\Column(type="string", length=190, unique=true, nullable=true)
      */
      private $slug;
  
      /**
      * @var Country
      *
      * @ORM\ManyToOne(targetEntity="Country", inversedBy="states", cascade={"all"})
      */
      private $country;
  
      /**
      * @var ArrayCollection $cities
      *
      * @ORM\OneToMany(targetEntity="City", mappedBy="state", fetch="EXTRA_LAZY", cascade={"all"})
      */
      private $cities;
  
  
  
      public function __construct()
      {
      $this-&gt;cities = new ArrayCollection();
      }
  
      /**
      * Get id
      *
      * @return integer 
      */
      public function getId()
      {
      return $this-&gt;id;
      }
  
      /**
      * Set shortName
      *
      * @param string $shortName
      * @return State
      */
      public function setShortName($shortName)
      {
      $this-&gt;shortName = $shortName;
  
      return $this;
      }
  
      /**
      * Get shortName
      *
      * @return string
      */
      public function getShortName()
      {
      return $this-&gt;shortName;
      }
  
      /**
      * Set slug
      *
      * @param string $slug
      * @return State
      */
      public function setSlug($slug)
      {
      $this-&gt;slug = $slug;
  
      return $this;
      }
  
      /**
      * Get slug
      *
      * @return string 
      */
      public function getSlug()
      {
      return $this-&gt;slug;
      }
  
      /**
      * Set country
      *
      * @param \Couponiacs\MainBundle\Entity\Country $country
      * @return State
      */
      public function setCountry(Country $country = null)
      {
      $this-&gt;country = $country;
  
      return $this;
      }
  
      /**
      * Get country
      *
      * @return \Couponiacs\MainBundle\Entity\Country 
      */
      public function getCountry()
      {
      return $this-&gt;country;
      }
  
      /**
      * Add city
      *
      * @param \Couponiacs\MainBundle\Entity\City $city
      * @return State
      */
      public function addCity(City $city)
      {
      $this-&gt;cities[] = $city;
  
      return $this;
      }
  
      /**
      * Remove city
      *
      * @param \Couponiacs\MainBundle\Entity\City $city
      */
      public function removeCity(City $city)
      {
      $this-&gt;cities-&gt;removeElement($city);
      }
  
      /**
      * Get cities
      *
      * @return \Doctrine\Common\Collections\Collection 
      */
      public function getCities()
      {
      return $this-&gt;cities;
      }
  }
  </code></pre>
  
  <p>Country entity:</p>
  
  <pre class="lang-php prettyprint-override"><code>    &lt;?php
  
  namespace Couponiacs\MainBundle\Entity;
  
  use Doctrine\ORM\Mapping as ORM;
  use Doctrine\Common\Collections\ArrayCollection;
  use Gedmo\Mapping\Annotation as Gedmo;
  use Gedmo\Timestampable\Traits\TimestampableEntity;
  use Symfony\Component\Validator\Constraints as Assert;
  use Couponiacs\MainBundle\Entity\Traits\UniqueNameEntity;
  use Couponiacs\MainBundle\Entity\Traits\EnabledEntity;
  
  /**
  * Country
  *
  * @ORM\Table()
  * @ORM\Entity(repositoryClass="Couponiacs\MainBundle\Entity\CountryRepository")
  */
  class Country
  {
      use TimestampableEntity;
      use UniqueNameEntity;
      use EnabledEntity;
  
      /**
      * @var integer
      *
      * @ORM\Column(type="integer")
      * @ORM\Id
      * @ORM\GeneratedValue(strategy="AUTO")
      */
      private $id;
  
      /**
      * @var string
      *
      * @ORM\Column(type="string", length=16, unique=true)
      * @Assert\NotBlank(message="err.constraint.empty_value")
      */
      private $shortName = '';
  
      /**
      * @var string
      *
      * @ORM\Column(type="string", length=64)
      */
      private $formatShort;
  
      /**
      * @var string
      *
      * @ORM\Column(type="string", length=64)
      */
      private $formatLong;
  
      /**
      * @var string
      *
      * @Gedmo\Slug(fields={"name"})
      * @ORM\Column(type="string", length=190, unique=true)
      * @Assert\NotBlank(message="err.constraint.empty_value")
      */
      private $slug;
  
      /**
      * @var ArrayCollection $states
      *
      * @ORM\OneToMany(targetEntity="State", mappedBy="country", fetch="EXTRA_LAZY", cascade={"all"})
      */
      private $states;
  
      /**
      * @var ArrayCollection $coupons
      *
      * @ORM\OneToMany(targetEntity="Coupon", mappedBy="country", fetch="EXTRA_LAZY", cascade={"all"})
      */
      private $coupons;
  
  
  
      public function __construct()
      {
      $this-&gt;states = new ArrayCollection();
      $this-&gt;coupons = new ArrayCollection();
      }
  
      /**
      * Get id
      *
      * @return integer 
      */
      public function getId()
      {
      return $this-&gt;id;
      }
  
      /**
      * Set shortName
      *
      * @param string $shortName
      * @return Country
      */
      public function setShortName($shortName)
      {
      $this-&gt;shortName = $shortName;
  
      return $this;
      }
  
      /**
      * Get shortName
      *
      * @return string
      */
      public function getShortName()
      {
      return $this-&gt;shortName;
      }
  
      /**
      * Set formatShort
      *
      * @param string $formatShort
      * @return Country
      */
      public function setFormatShort($formatShort)
      {
      $this-&gt;formatShort = $formatShort;
  
      return $this;
      }
  
      /**
      * Get formatShort
      *
      * @return string
      */
      public function getFormatShort()
      {
      return $this-&gt;formatShort;
      }
  
      /**
      * Set formatLong
      *
      * @param string $formatLong
      * @return Country
      */
      public function setFormatLong($formatLong)
      {
      $this-&gt;formatLong = $formatLong;
  
      return $this;
      }
  
      /**
      * Get formatLong
      *
      * @return string
      */
      public function getFormatLong()
      {
      return $this-&gt;formatLong;
      }
  
      /**
      * Set slug
      *
      * @param string $slug
      * @return Country
      */
      public function setSlug($slug)
      {
      $this-&gt;slug = $slug;
  
      return $this;
      }
  
      /**
      * Get slug
      *
      * @return string 
      */
      public function getSlug()
      {
      return $this-&gt;slug;
      }
  
      /**
      * Add state
      *
      * @param \Couponiacs\MainBundle\Entity\State $state
      * @return Country
      */
      public function addState(State $state)
      {
      $this-&gt;states[] = $state;
  
      return $this;
      }
  
      /**
      * Remove state
      *
      * @param \Couponiacs\MainBundle\Entity\State $state
      */
      public function removeState(State $state)
      {
      $this-&gt;states-&gt;removeElement($state);
      }
  
      /**
      * Get states
      *
      * @return \Doctrine\Common\Collections\Collection 
      */
      public function getStates()
      {
      return $this-&gt;states;
      }
  
      /**
      * Add coupon
      *
      * @param \Couponiacs\MainBundle\Entity\Coupon $coupon
      * @return Country
      */
      public function addCoupon(Coupon $coupon)
      {
      $this-&gt;coupons[] = $coupon;
  
      return $this;
      }
  
      /**
      * Remove coupon
      *
      * @param \Couponiacs\MainBundle\Entity\Coupon $coupon
      */
      public function removeCoupon(Coupon $coupon)
      {
      $this-&gt;coupons-&gt;removeElement($coupon);
      }
  
      /**
      * Get coupons
      *
      * @return \Doctrine\Common\Collections\Collection
      */
      public function getCoupons()
      {
      return $this-&gt;coupons;
      }
  }
  </code></pre>