我认为这可能是与这个问题类似的问题,但我还不能发表评论,也不想通过提供无答案的答案来解决这个问题。
我正在制作一个评论 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 实体中检索 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 方法工作或另一种可行的方法?谢谢