Solución:
-
Creo que hibernate primero traduce su consulta HQL a SQL y solo después de eso intenta vincular sus parámetros. Lo que significa que no podrá reescribir la consulta desde
param = ?
paraparam is null
. -
Intente usar Criteria api:
Criteria c = session.createCriteria(CountryDTO.class); c.add(Restrictions.eq("type", type)); c.add(status == null ? Restrictions.isNull("status") : Restrictions.eq("status", status)); List result = c.list();
Este no es un problema específico de Hibernate (es solo la naturaleza de SQL), y SÍ, hay una solución tanto para SQL como para HQL:
@Peter Lang tuvo la idea correcta y usted tenía la consulta HQL correcta. Supongo que solo necesitaba una nueva ejecución limpia para recoger los cambios de consulta 😉
El siguiente código funciona absolutamente y es genial si mantiene todas sus consultas en orm.xml
from CountryDTO c where ((:status is null and c.status is null) or c.status = :status) and c.type =:type
Si su parámetro String es nulo, la consulta comprobará si el estado de la fila también es nulo. De lo contrario recurrirá a comparar con el signo igual.
Notas:
El problema puede ser una peculiaridad específica de MySql. Solo probé con Oracle.
La consulta anterior asume que hay filas de tabla donde c.status es nulo
La cláusula where tiene prioridad para que el parámetro se verifique primero.
El nombre del parámetro ‘tipo’ puede ser una palabra reservada en SQL, pero no debería importar, ya que se reemplaza antes de que se ejecute la consulta.
Si necesita omitir: status where_clause por completo; puedes codificar así:
from CountryDTO c where (:status is null or c.status = :status) and c.type =:type
y es equivalente a:
sql.append(" where ");
if(status != null){
sql.append(" c.status = :status and ");
}
sql.append(" c.type =:type ");
El javadoc para setParameter(String, Object)
es explícito, diciendo que el valor del objeto no debe ser nulo. Sin embargo, es una pena que no genere una excepción si se pasa un nulo.
Una alternativa es setParameter(String, Object, Type)
, cuales lo hace permitir valores nulos, aunque no estoy seguro de qué Type
El parámetro sería el más apropiado aquí.