2
我有這樣的實體:Doctrine2在ZF2 - DQL給出不同的結果findOneBy方法
/**
* User state.
*
* @ORM\Entity(repositoryClass="User\Repository\StateRepository")
* @ORM\Table(name="user_state")
*/
class State implements StateInterface
{
/** ONE-TO-ONE BIDIRECTIONAL, OWNING SIDE
* @var User
* @ORM\Id
* @ORM\OneToOne(targetEntity="User\Entity\User", inversedBy="state")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
/** ONE-TO-ONE UNIDIRECTIONAL
* @var \Application\Entity\State
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Application\Entity\State", fetch="EAGER")
* @ORM\JoinColumn(name="state_id", referencedColumnName="id")
*/
protected $state;
public function __construct(User $user, \Application\Entity\State $state)
{
$this->user = $user;
$this->state = $state;
}
/********/
/* USER */
/********/
/**
* Get user
*
* @return User
*/
public function getUser()
{
return $this->user;
}
/**
* Set user
*
* @param User $user
*
* @return Email
*/
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
/**********/
/* STATUS */
/**********/
/**
* Get state
*
* @return \Application\Entity\State
*/
public function getState()
{
return $this->state;
}
/**
* Set state
*
* @param \Application\Entity\State $state
*
* @return State
*/
public function setState(\Application\Entity\State $state)
{
$this->state = $state;
return $this;
}
/******/
/* ID */
/******/
/**
* Get id.
*
* @return int
*/
public function getId()
{
return $this->state->getId();
}
/**
* Set id.
*
* @param int $id
*
* @return State
*/
public function setId($id)
{
$this->state->setId((int) $id);
return $this;
}
/********/
/* NAME */
/********/
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->state->getName();
}
/**
* Set name
*
* @param string $name
*
* @return State
*/
public function setName($name)
{
$this->state->setName((string) $name);
return $this;
}
}
而且去取我在我的自定義存儲庫這樣做實體
return self::findOneBy($params);
導致此查詢:
SELECT t0.user_id AS user_id1, t0.state_id AS state_id2, t3.id AS id4, t3.name AS name5 FROM user_state t0 LEFT JOIN state t3 ON t0.state_id = t3.id WHERE t0.user_id = ? LIMIT 1
完美!正是我想要的和相關的實體是因爲fetch="EAGER"
上的關係,預先抓取。 現在我想實現與DQL一樣,所以我這樣做:
$query = $this->_em->createQuery("SELECT us, s FROM 'User\Entity\State' us LEFT JOIN us.state s WHERE us.user = :user_id");
$query->setParameters($params);
$query->setFetchMode('User\Entity\State', 'state', ClassMetadata::FETCH_EAGER);
return $query->getOneOrNullResult();
我收到一條錯誤消息:Call to a member function getId() on a non-object
顯然,相關實體加載不正確。當我手動檢查$state
原來是NULL
如果我在這樣的查詢ommit的S:
$query = $this->_em->createQuery("SELECT us FROM 'User\Entity\State' us LEFT JOIN us.state s WHERE us.user = :user_id");
然後返回結果正是我想要的,但它會導致兩個查詢(額外的查詢來獲得相關國家實體),這顯然是有道理的,因爲該查詢不被視爲一個fetch join
任何更長的時間,所以延遲加載相關實體。
我怎樣才能得到相同的結果(一個查詢,一個結果),因爲我使用的方法findOneBy
但比使用DQL得到了什麼?
[這個問題](HTTP ://stackoverflow.com/questions/9020433/doctrine2-loads-one-to-many-associations-with-fetch-mode-eager-using-too-many-sq)可能會有所幫助 – AlexP
@AlexP我試過'LEFT JOIN '但沒有什麼區別,仍然拋出'呼籲在非object' – Wilt
@AlexP我更新了我的問題了'LEFT JOIN'查詢一個成員函數的getId()。 – Wilt