我认为这可能与this question有类似的问题,但我无法发表评论,也不想通过提供非答案答案来解决这个问题。
我正在评论Symfony2包,它允许我直接将注释与各种不同的实体类型相关联,所以我创建了一个抽象注释'thread'实体,然后由每个对象类型的具体线程实体扩展可以收到评论。
因此,例如,它需要可以对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();
}
最后,我将尝试从给定的Story实体中检索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 :(得分:1)
我原本以为我需要提供对象,因为'故事'列指的是一个故事实体,但事实证明我只需要使用id:
$thread = $repository->findOneBy(array(
$repository->getObjectColumn() => $object->getId()
));