Reputation: 418
I have a class, let's say Test.php. This class has an id, a description, a code, and a discount percentage.
This code returns an object:
$test = $this->getDoctrine()->getRepository('\UserBundle\Entity\Test')->findOneBy(array('code' => 12345 ));
This code, instead, doesn't return an object:
$test = $this->getDoctrine()->getRepository('\UserBundle\Entity\Test')->findOneBy(array('code' => null ));
The code field is NULL by default.
Any suggestion? Thanks!
Upvotes: 2
Views: 8046
Reputation: 7199
You just can use doctrine expressions in TestRepository
class
$db = $this->createQueryBuilder('t');
return $db->select('t')
->where($db->expr()->isNull('t.field1'))
->orWhere($db->expr()->isNull('t.field2'))
->orWhere($db->expr()->isNull('t.field3'))
->getQuery()
->getResult();
Upvotes: 0
Reputation: 71
While qooplmao is correct for the first part "To query for a null
value you need to use is null
rather than = null
", I have to say that the second part "which the Doctrine shortcut don't do" is not true (at least for version 2.5.4, which was the latest stable release at the time of the question).
\Doctrine\ORM\EntityRepository::findOneBy() (with argument array('code' => null)
) ultimately calls
\Doctrine\ORM\Persisters\Entity\BasicEntityPersister::getSelectConditionStatementSQL() (with arguments 'code', null, null
), which does handle the special case of a null value (shortened to the essential here, $columns
is an array with a single element e.g. array('t0.code')
, $value
is null
):
foreach ($columns as $column) {
$placeholder = '?';
...
if (null === $value) {
$selectedColumns[] = sprintf('%s IS NULL', $column);
continue;
}
$selectedColumns[] = sprintf('%s = %s', $column, $placeholder);
}
and then executes a SQL query with a correct condition, of the form:
SELECT t0.id AS id_1, t0.description AS description_2, t0.code AS code_3, ...
FROM Test t0
WHERE t0.code IS NULL
LIMIT 1
(It even handles null in an array value, e.g. with argument array('code' => array(12345, null, 42))
, it will generate a SQL condition of the form
WHERE (t0.code IN (12345, NULL, 42) OR t0.code IS NULL)
(actually it could remove the NULL
from the IN
, but the result is the same).)
Edit: That has been the case since version 2.5.0 for both simple and array values (thanks to commit 733102b4a109c0bb8ca026b1dbbadaa9bb62ae70), and even since version 2.1.0 for simple (non-array) values (like your case) (thanks to commit a3290075260cdafdd17952ca14daa305fabccfe2).
So the fact that your findOneBy(array('code' => null ))
didn't return an object can only mean that your table just didn't have any row with column code
set to NULL
, which seems confirmed by your discussion with qooplmao in the comments of their answer, and so if you retry now with your new data, it should return an object the same as with a QueryBuilder or DQL.
Upvotes: 2
Reputation: 17759
Taken from this answer
In SQL, a comparison between a null value and any other value (including another null) a using a logical operator (eg =, !=, <, etc) will result in a null, which is considered as false for the purposes of a where clause. The reasoning is that a null means "unknown", so the result of any comparison to a null is also "unknown".
To query for a null
value you need to use is null
rather than = null
which the Doctrine shortcut don't do. You would need to do this by using SQL/DQL directly or the query builder like...
/** QueryBuilder */
$test = $this
->getDoctrine()
->getRepository('\UserBundle\Entity\Test')
->createQueryBuilder('t')
->where('t.code is null')
->getQuery()
->getResult();
/**
* Alternatively, if trying to find a single record you can use ->getOneOrNullResult();
* as ->getResult() will throw a NoResultException if no results are found
*/
/** DQL */
$test = $this
->getDoctrine()
->createQuery('
SELECT t
FROM \UserBundle\Entity\Test t
WHERE t.code is null
')
->getResult()
->getOneOrNullResult();
Upvotes: 4