When I try to use the Doctrine\ORM\Query#getOneOrNullResult method with HYDRATE_SINGLE_SCALAR as hydration mode, a Doctrine\ORM\NoResultException is thrown when no results are found:
$q=$em->createQueryBuilder()
->select('ticket.tickets_id')
->from('e:Ticket','ticket')
->where('ticket.ticketnumber=:ticketnumber')
->setParameter('ticketnumber','kr1r9x')
->getQuery()
;
// these both work:
var_dump($q->getOneOrNullResult(Query::HYDRATE_SCALAR));
var_dump($q->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR));
$q=$em->createQueryBuilder()
->select('ticket.tickets_id')
->from('e:Ticket','ticket')
->where('ticket.ticketnumber=:ticketnumber')
->setParameter('ticketnumber','foobar')
->getQuery()
;
// this works
var_dump($q->getOneOrNullResult(Query::HYDRATE_SCALAR));
// this fails
var_dump($q->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR));
I would expect NULL to be returned on that last call, but the actual output is:
% php ~/test.php
array(1) {
'tickets_id' =>
string(6) "119827"
}
string(6) "119827"
NULL
Fatal error: Uncaught exception 'Doctrine\ORM\NoResultException' with message 'No result was found for query although at least one row was expected.' in ~/project/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php on line 43
Doctrine\ORM\NoResultException: No result was found for query although at least one row was expected. in ~/project/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/SingleScalarHydrator.php on line 43
Call Stack:
0.0002 640440 1. {main}() ~/test.php:0
0.1575 15011776 2. Doctrine\ORM\AbstractQuery->getOneOrNullResult() ~/test.php:28
0.1575 15011824 3. Doctrine\ORM\AbstractQuery->execute() ~/project/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php:612
0.1581 15016432 4. Doctrine\ORM\Internal\Hydration\AbstractHydrator->hydrateAll() ~/project/vendor/doctrine/orm/lib/Doctrine/ORM/AbstractQuery.php:804
0.1581 15016432 5. Doctrine\ORM\Internal\Hydration\SingleScalarHydrator->hydrateAllData() ~/project/vendor/doctrine/orm/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php:140
Is it not possible to get a single scalar or NULL in this manner?
(I understand that the workaround is to use HYDRATE_SCALAR instead, I'm just wondering why HYDRATE_SINGLE_SCALAR doesn't work)
Doctrine ORM v2.4.5, DBAL & Common v2.4.2
NULL is not a scalar value, so it is correct for doctrine to throw an exception when no row is found.
The proper way to handle this is to catch and handle the exception. You might choose to set the result to NULL, perform another action, or abstract the exception by throwing your own. For example, if you're trying to set a variable to the result:
// After defining QueryBuilder $q
try {
$result = $q->getOneOrNullResult(Query::HYDRATE_SINGLE_SCALAR);
} catch (\Doctrine\ORM\NoResultException $e) {
// Handle the exception here. In this case, we are setting the variable to NULL
$result = null;
}
As far as the difference between HYDRATE_SCALAR and HYDRATE_SINGLE_SCALAR: HYDRATE_SINGLE_SCALAR returns one and only one value, so if it has no values to return, it must throw an error. HYDRATE_SCALAR returns an array of any number of values including 0, so it's OK for it to return 0 results.