我有一个使用Doctrine2的symfony2应用程序,以及一些City,State,Country,Address的实体。
问题在于,如果我这样做:
$queryBuilder = $this->em->createQueryBuilder();
$queryBuilder
->select(array('country', 'state', 'city', 'address'))
->from('CouponiacsMainBundle:Country', 'country')
->leftJoin('country.states', 'state', 'WITH', 'state.name=:stateName OR state.shortName=:stateShortName')
->leftJoin('state.cities', 'city', 'WITH', 'city.name=:cityName')
->leftJoin('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')
->orderBy('city.name', 'DESC')
->setParameters(array(
'countryName' => $country,
'countryShortName' => $countryShort,
'stateName' => $state,
'stateShortName' => $stateShort,
'cityName' => $city,
'address' => $address['address'],
'zip' => $address['zip'],
'latitude' => $address['latitude'],
'longitude' => $address['longitude'],
))
->setMaxResults(1);
结果集仅包含Country实体,但不包含State实体。我也尝试使用DQL进行相同的查询但没有成功:
$query = $this->em->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
')->setParameters(array(
'countryName' => $country,
'countryShortName' => $countryShort,
'stateName' => $state,
'stateShortName' => $stateShort,
'cityName' => $city,
'address' => $address['address'],
'zip' => $address['zip'],
'latitude' => $address['latitude'],
'longitude' => $address['longitude'],
));
如果我手动运行生成的SQL,则状态的结果是正常的,但在结果集上没有状态实体。结果是一个带有Country实体的数组,如果我执行getStates(),我就没有状态。
任何建议表示赞赏, 谢谢!
修改: 这是学说映射:
地址实体:
<?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->coupons = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set address
*
* @param string $address
* @return Address
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* Get address
*
* @return string
*/
public function getAddress()
{
return $this->address;
}
/**
* Set zip
*
* @param string $zip
* @return Coupon
*/
public function setZip($zip)
{
$this->zip = $zip;
return $this;
}
/**
* Get zip
*
* @return string
*/
public function getZip()
{
return $this->zip;
}
/**
* Set latitude
*
* @param string $latitude
* @return Coupon
*/
public function setLatitude($latitude)
{
$this->latitude = $latitude;
return $this;
}
/**
* Get latitude
*
* @return string
*/
public function getLatitude()
{
return $this->latitude;
}
/**
* Set longitude
*
* @param string $longitude
* @return Coupon
*/
public function setLongitude($longitude)
{
$this->longitude = $longitude;
return $this;
}
/**
* Get longitude
*
* @return string
*/
public function getLongitude()
{
return $this->longitude;
}
/**
* Set city
*
* @param \Couponiacs\MainBundle\Entity\City $city
* @return Address
*/
public function setCity(City $city = null)
{
$this->city = $city;
return $this;
}
/**
* Get city
*
* @return \Couponiacs\MainBundle\Entity\City
*/
public function getCity()
{
return $this->city;
}
/**
* Add coupon
*
* @param \Couponiacs\MainBundle\Entity\Coupon $coupon
* @return Address
*/
public function addCoupon(Coupon $coupon)
{
$this->coupons[] = $coupon;
return $this;
}
/**
* Remove coupon
*
* @param \Couponiacs\MainBundle\Entity\Coupon $coupon
*/
public function removeCoupon(Coupon $coupon)
{
$this->coupons->removeElement($coupon);
}
/**
* Get coupons
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCoupon()
{
return $this->coupons;
}
}
城市实体:
<?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->addresses = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set slug
*
* @param string $slug
* @return City
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set state
*
* @param \Couponiacs\MainBundle\Entity\State $state
* @return City
*/
public function setState(State $state = null)
{
$this->state = $state;
return $this;
}
/**
* Get state
*
* @return \Couponiacs\MainBundle\Entity\State
*/
public function getState()
{
return $this->state;
}
/**
* Add address
*
* @param \Couponiacs\MainBundle\Entity\Address $address
* @return City
*/
public function addAddress(Address $address)
{
$this->addresses[] = $address;
return $this;
}
/**
* Remove address
*
* @param \Couponiacs\MainBundle\Entity\Address $address
*/
public function removeAddress(Address $address)
{
$this->addresses->removeElement($address);
}
/**
* Get addresses
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getAddresses()
{
return $this->addresses;
}
}
州实体:
<?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->cities = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set shortName
*
* @param string $shortName
* @return State
*/
public function setShortName($shortName)
{
$this->shortName = $shortName;
return $this;
}
/**
* Get shortName
*
* @return string
*/
public function getShortName()
{
return $this->shortName;
}
/**
* Set slug
*
* @param string $slug
* @return State
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Set country
*
* @param \Couponiacs\MainBundle\Entity\Country $country
* @return State
*/
public function setCountry(Country $country = null)
{
$this->country = $country;
return $this;
}
/**
* Get country
*
* @return \Couponiacs\MainBundle\Entity\Country
*/
public function getCountry()
{
return $this->country;
}
/**
* Add city
*
* @param \Couponiacs\MainBundle\Entity\City $city
* @return State
*/
public function addCity(City $city)
{
$this->cities[] = $city;
return $this;
}
/**
* Remove city
*
* @param \Couponiacs\MainBundle\Entity\City $city
*/
public function removeCity(City $city)
{
$this->cities->removeElement($city);
}
/**
* Get cities
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCities()
{
return $this->cities;
}
}
国家/地区实体:
<?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->states = new ArrayCollection();
$this->coupons = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set shortName
*
* @param string $shortName
* @return Country
*/
public function setShortName($shortName)
{
$this->shortName = $shortName;
return $this;
}
/**
* Get shortName
*
* @return string
*/
public function getShortName()
{
return $this->shortName;
}
/**
* Set formatShort
*
* @param string $formatShort
* @return Country
*/
public function setFormatShort($formatShort)
{
$this->formatShort = $formatShort;
return $this;
}
/**
* Get formatShort
*
* @return string
*/
public function getFormatShort()
{
return $this->formatShort;
}
/**
* Set formatLong
*
* @param string $formatLong
* @return Country
*/
public function setFormatLong($formatLong)
{
$this->formatLong = $formatLong;
return $this;
}
/**
* Get formatLong
*
* @return string
*/
public function getFormatLong()
{
return $this->formatLong;
}
/**
* Set slug
*
* @param string $slug
* @return Country
*/
public function setSlug($slug)
{
$this->slug = $slug;
return $this;
}
/**
* Get slug
*
* @return string
*/
public function getSlug()
{
return $this->slug;
}
/**
* Add state
*
* @param \Couponiacs\MainBundle\Entity\State $state
* @return Country
*/
public function addState(State $state)
{
$this->states[] = $state;
return $this;
}
/**
* Remove state
*
* @param \Couponiacs\MainBundle\Entity\State $state
*/
public function removeState(State $state)
{
$this->states->removeElement($state);
}
/**
* Get states
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getStates()
{
return $this->states;
}
/**
* Add coupon
*
* @param \Couponiacs\MainBundle\Entity\Coupon $coupon
* @return Country
*/
public function addCoupon(Coupon $coupon)
{
$this->coupons[] = $coupon;
return $this;
}
/**
* Remove coupon
*
* @param \Couponiacs\MainBundle\Entity\Coupon $coupon
*/
public function removeCoupon(Coupon $coupon)
{
$this->coupons->removeElement($coupon);
}
/**
* Get coupons
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCoupons()
{
return $this->coupons;
}
}
答案 0 :(得分:0)
问题很可能是您在其他查询之前使用其中一些实体。并且Doctrine保留了一些缓存的东西。它取决于关联是完全加载还是仅部分加载。加载新的实体管理器或其他实体管理器应该可以解决问题。