2012-05-14 82 views
1

我認爲這可能是一個類似的問題this question,但我不能評論,並不想通過提供一個非答案的答案碰撞。Doctrine2 findOneBy方法返回null使用JOINED繼承映射

我正在評論Symfony2包,它允許我直接將註釋與各種不同的實體類型關聯起來,所以我創建了一個抽象註釋「線索」實體,然後由每個對象類型的具體線程實體可以收到評論。

因此,例如它需要可以評論Story實體,所以我創建了一個具體的StoryThread實體,它擴展了Thread並指定了鏈接到Story的OneToOne屬性。這個想法是,我可以做$storyThread->findOneBy('story', $story)->getComments();。但是,findOneBy總是返回null。當我運行從調試中檢索到的原始SQL並填入相關的story_id時,我確實收回了預期的結果。

這裏是抽象的線實體:

use Doctrine\ORM\Mapping as ORM; 
use Gedmo\Mapping\Annotation as Gedmo; 
use Doctrine\Common\Collections\ArrayCollection; 

/** 
* @ORM\Entity(repositoryClass="Joe\Bundle\CommentBundle\Repository\ThreadRepository") 
* @ORM\Table(name="comment_threads") 
* @ORM\MappedSuperClass 
* @ORM\InheritanceType("JOINED") 
* @ORM\DiscriminatorColumn(name="thread_type", type="string") 
* @ORM\DiscriminatorMap({"story" = "Joe\Bundle\StoryBundle\Entity\StoryThread"}) 
*/ 
abstract class Thread 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\Column(type="boolean") 
    */ 
    protected $enabled = true; 

    /** 
    * @var datetime $createdAt 
    * 
    * @Gedmo\Timestampable(on="create") 
    * @ORM\Column(name="created_at", type="datetime") 
    */ 
    protected $createdAt; 

    /** 
    * @ORM\OneToMany(targetEntity="Comment", mappedBy="thread_id", cascade={"persist"}) 
    * @param ArrayCollection $data 
    */ 
    protected $comments; 


    function __construct() 
    { 
     $this->comments = new ArrayCollection(); 
    } 

,這裏是具體的StoryThread實體:

use Doctrine\ORM\Mapping as ORM; 
use Joe\Bundle\CommentBundle\Entity\Thread as AbstractThread; 

/** 
* @ORM\Entity(repositoryClass="Joe\Bundle\StoryBundle\Repository\StoryThreadRepository") 
* @ORM\Table(name="story_comment_threads") 
*/ 
class StoryThread extends AbstractThread 
{ 
    /** 
    * @ORM\OneToOne(targetEntity="Story") 
    * @ORM\JoinColumn(name="story_id", referencedColumnName="id") 
    */ 
    protected $story; 

    /** 
    * @var datetime $createdAt 
    */ 
    protected $createdAt; 


    public function __construct() 
    { 
     $this->comments = new \Doctrine\Common\Collections\ArrayCollection(); 
    } 

最後在這裏是如何我試圖從一個給定的檢索StoryThread對象故事實體:(getThreadEntityName獲取完全限定的StoryThread類名,getObjectColumn返回用於將ObjectThread實體映射到其對象的列的名稱,因此在這種情況下爲「故事」)

/** 
* @param CommentableInterface $object 
* @return AbstractThread 
*/ 
public function findThreadByObject(CommentableInterface $object) 
{ 
    /** @var $repository ThreadRepository */ 
    $repository = $this->em->getRepository($object->getThreadEntityName()); 

    $thread = $repository->findOneBy(array(
     $repository->getObjectColumn() => $object 
    )); 

    if (!$thread) { 
     $thread = $this->createThread($object); 
    } 

    return $thread; 
} 

這裏是在findOneBy方法中生成的SQL :(當我替換?與實際的故事ID,如1,我回去,我會期望一個結果)

SELECT t1.id AS id2, t1.enabled AS enabled3, t1.created_at AS created_at4, t0.story_id AS story_id5, t1.thread_type FROM story_comment_threads t0 INNER JOIN comment_threads t1 ON t0.id = t1.id WHERE t0.story_id = ?

誰能告訴我怎樣可以得到findOneBy方法工作或者是另一種方法那會工作?由於

+0

做你嘗試$ storyThread-> findOneBystory($ story) - > getComments(); ?? –

+0

對不起,我沒有機會嘗試,直到現在。這產生了相同的結果。然而,自從昨天發佈這篇文章以來,我的額外一天讓我嘗試使用$ object-> getId()作爲值,而這似乎已經成功了! :) – RobMasters

回答

1

我還以爲我需要提供對象看到的「故事」列指的是故事的實體,但事實證明,我只需要使用而不是ID:

$thread = $repository->findOneBy(array(
    $repository->getObjectColumn() => $object->getId() 
));