Cómo consultar una fecha en HQL (Hibernate) con Joda Time?
Pregunta
Estoy seguro de que alguien familiarizado con HQL (yo soy yo un novato) puede responder fácilmente a esta pregunta.
En mi aplicación Grails, tengo la siguiente clase de dominio.
class Book {
org.joda.time.DateTime releaseDate //I use the PersistentDateTime for persisting via Hibernate (that use a DATETIME type for MySQL DB)
}
En mi consulta HQL, quiero recuperar libros cuya fecha de lanzamiento está incluido en date1
..date2
gama
Por ejemplo Traté:
DateTime date1, date2
...
def queryStr = "select * from Book as b where b.releaseDate > $date1 and b.releaseDate < $date2"
def res = Book.executeQuery(queryStr)
Pero tengo la excepción ...caused by: org.springframework.orm.hibernate3.HibernateQueryException: unexpected token:
Los puntos de distintivo de error a formato de fecha (por ejemplo 2009-11-27T21:57:18.010+01:00
o Fri Nov 27 22:01:20 CET 2009
)
También he tratado de convertir en una clase fecha1 fecha sin éxito
Entonces, ¿cuál es el código de HQL correcta? Debería convertir a un formato específico (¿cuál?) Usando el método patternForStyle o hay otra manera de hacerlo -cleaner-?
Gracias,
Fabien.
Solución
No soy un experto Grails, pero en java que normalmente haría parámetros de consulta y date1
date2
y se unen como tal:
String hql = "select * from Book as b where b.releaseDate > :date1 and b.releaseDate < :date2";
session.createQuery(hql).setDate("date1", date1).setDate("date2", date2).list();
Estoy seguro de que puede hacer algo similar en Grails. Si no es así, dar formato a fechas como yyyyMMddhhmmss
(sin espacios) y encerrarlas entre comillas simples -. De esa manera Hibernate los trataría como constantes y MySQL implícitamente convertirlos en fechas
Otros consejos
he señalado por ChssPly, debe declarar date1
y date2
como parámetros de consulta (posicionales o nombre) y luego atarlos. A continuación, vamos a utilizar parámetros con nombre. La forma habitual de pasar parámetros de consulta con nombre con Grails es a través de un Map
:
def queryStr = "from Book b where b.releaseDate > :date1 and b.releaseDate < :date2"
Book.executeQuery(queryStr, [date1: date1, date2: date2])
executeQuery()
documentación para la sintaxis detalles de ambas opciones.
También puede comparar fechas utilizando el formato de fecha ISO8601 por ejemplo:
select * from Book as b
where b.releaseDate > '2009-11-27T21:57:18.010+01:00'
and b.releaseDate < '2010-11-27T21:57:18.010+01:00'
He probado esto usando MySQL como el extremo posterior. Sólo recuerde que debe envolver las fechas como una cadena.