I think this is possibly a similar issue to this question but I'm not able to comment yet and didn't want to bump it by providing a non-answer answer.
I'm making a commenting Symfony2 bundle that allows me to directly relate comments to various different entity types, so I've created an abstract comment 'thread' entity, which is then extended by a concrete thread entity per object type that can receive comments.
So for example it needs to be possible to comment on the Story entity, so I've created a concrete StoryThread entity that extends Thread and specifies a OneToOne attribute that links to the Story. The idea being that I can then do $storyThread->findOneBy('story', $story)->getComments();
. However, findOneBy always returns null. When I run the raw SQL that I retrieved from debugging into it and fill in the relevant story_id, I do get back the expected result.
Here is the abstract thread entity:
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();
}
and here is the concrete StoryThread entity:
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();
}
And finally here is how I'm trying to retrieve the StoryThread object from a given Story entity: (getThreadEntityName gets the fully qualified StoryThread class name, and getObjectColumn returns the name of the column used to map an ObjectThread entity to it's object, so in this case "story")
/**
* @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;
}
Here is the SQL that is generated within the findOneBy method: (when I replace ? with an actual story id, such as 1, I get back a single result as I'd expect)
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 = ?
Could anyone tell me how I can either get the findOneBy method to work or perhaps an alternative way that would work? Thanks