2014-05-15 28 views
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得到了什麼?

+0

[這個問題](HTTP ://stackoverflow.com/questions/9020433/doctrine2-loads-one-to-many-associations-with-fetch-mode-eager-using-too-many-sq)可能會有所幫助 – AlexP

+0

@AlexP我試過'LEFT JOIN '但沒有什麼區別,仍然拋出'呼籲在非object' – Wilt

+0

@AlexP我更新了我的問題了'LEFT JOIN'查詢一個成員函數的getId()。 – Wilt

回答

0

我剛剛更新了我的Doctrine2 ORM到2.5版本,現在它的工作:)

我目前composer.json文件看起來像這裏面的教義元素:

"doctrine/doctrine-module":"dev-master", 
"doctrine/doctrine-orm-module": "dev-master", 
"doctrine/dbal": "2.5.*@dev", 
"doctrine/orm": "2.5.*@dev", 
相關問題