I have a working SQL query which returns rows from the SQL commandline, but not when submitted through Doctrine. I think the problem is in how I'm setting the ResultSetMapper
. I've read the docs about native queries but I must be missing something. What is it?
The following query run from the SQL commandline produces 1 row:
SELECT t.*
FROM
StateLogItem s NATURAL JOIN (
SELECT
task_id,
MAX(
COALESCE(updatedAt, createdAt)
) d,
MAX(id) id
FROM
StateLogItem
WHERE
dtype = 'transitionlogitem'
GROUP BY
task_id
) m
RIGHT JOIN Task t ON t.id = s.task_id
WHERE s.toState = 'started';
'20', 1, NULL, 'just because', '2014-07-18 10:49:00', NULL
ResultSetMapping
When I attempt to run the same query via Doctrine in a Symfony EntityRepository (as follows), I get zero rows even though the Symfony profiler indicates that the correct query was successfully run.
public function findByActionStatus($status){
$sql = "SELECT t.id, t.description, t.created_by, t.updated_by, t.createdAt, t.updatedAt
FROM StateLogItem s
NATURAL JOIN (
SELECT task_id, MAX(COALESCE(updatedAt,createdAt)) d, MAX(id) id
FROM StateLogItem
WHERE dtype = 'transitionlogitem'
GROUP BY task_id
) m
RIGHT JOIN Task t ON t.id=s.task_id
WHERE s.toState = :status";
$em = $this->getEntityManager();
$rsm = new ResultSetMapping();
$rsm->addEntityResult('ACCQueueBundle:Task', 't');
$rsm->addFieldResult('t','t.id','id');
$rsm->addFieldResult('t','t.created_by','createdBy');
$rsm->addFieldResult('t','t.updated_by','updatedBy');
$rsm->addFieldResult('t','t.description','description');
$rsm->addFieldResult('t','t.createdAt','createdAt');
$rsm->addFieldResult('t','t.updatedAt','updatedAt');
$rsm->addJoinedEntityResult('ACCQueueBundle:TransitionLogItem','s','t','transitions'); //tried with and without
$query = $em->createNativeQuery($sql,$rsm);
$query->setParameter('status', $status);
return $query->getResult();
}
The Task
entity looks like this:
namespace ACC\QueueBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use ACC\Traits\BlameableTrait;
use ACC\MainBundle\Entity\Traits\HasDocumentsTrait;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Timestampable\Traits\TimestampableEntity;
/**
* Task
* @ORM\Entity(repositoryClass="ACC\QueueBundle\Entity\TaskRepository")
* @ORM\HasLifecycleCallbacks()
*
*/
class Task {
use HasDocumentsTrait;
use BlameableTrait;
use TimestampableEntity;
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var Transition
*
* @ORM\OneToMany(targetEntity = "TransitionLogItem", mappedBy = "task", orphanRemoval = true, cascade = {"persist"})
* @ORM\OrderBy({"createdAt" = "ASC"})
*/
protected $transitions;
/**
* @var Pause
*
* @ORM\OneToMany(targetEntity = "PauseLogItem", mappedBy = "task", orphanRemoval = true, cascade = {"persist"})
* @ORM\OrderBy({"createdAt" = "ASC"})
*/
protected $pauses;
/**
* @var string
*
* @ORM\Column(name="description", type="text")
*/
protected $description;
/**
* @ORM\ManyToMany(targetEntity = "ACC\MainBundle\Entity\Document", cascade={"persist","remove"})
* @ORM\JoinTable(name="Task_Document",
* joinColumns={@ORM\JoinColumn(name="task_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="document_id", referencedColumnName="id", unique=true)})
*/
protected $documents;
//etc.
Well I found the problem. It is caused by ResultSetMapping
not understanding the query field names I gave it because I included the table prefix. So I can either not include the table prefix,
i.e. change $rsm->addFieldResult('t','t.id','id');
to $rsm->addFieldResult('t','id','id');
or I can alias all the fields:
i.e. change SELECT t.id, t.description...
to SELECT t.id AS t_id, t.description AS t_description...
In my case there was no result because in the SQL query I didn't selected the column "id" of the "main" entity (the one in the FROM clause).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With