2009-12-04 27 views
8

Estoy seguro de que alguien familiarizado con HQL (soy un novato) puede responder fácilmente a esta pregunta.¿Cómo consultar una fecha en HQL (Hibernar) con Joda Time?

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á incluida en el rango date1 .. date2

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: El token de error señala el formato de fecha (por ejemplo 2009-11-27T21:57:18.010+01:00 o Fri Nov 27 22:01:20 CET 2009)

También intenté convertir date1 en una clase Date sin éxito

¿Cuál es el código HQL correcto? ¿Debería convertir a un formato específico (¿cuál?) Usando el método patternForStyle o ¿hay alguna otra forma más clara de hacerlo?

Gracias,

Fabien.

+0

¿Cómo se relaciona org.joda.time.DateTime con su SQL? ¿Está directamente al campo? java.util.Date y java.util.Calendar pueden asignarse directamente a un campo de base de datos. Por lo que vale, dado que DateTime es un objeto agregado, el plugin de Grails probablemente esté utilizando debajo de las cubiertas un tipo de mapeo personalizado (ver sec 5.3 de Java Persistence con Hibernate). – Alan

+0

Como se indica en el comentario del código, DateTime utiliza el tipo de asignación personalizada PersistentDateTime de la biblioteca joda-time-hibernate – fabien7474

Respuesta

7

No soy un experto Grails, pero en java que normalmente hacen date1 y date2 parámetros de consulta y se unen como tales:

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. De lo contrario, formatee sus fechas como yyyyMMddhhmmss (sin espacios) y colóquelas entre comillas simples, de esta forma Hibernate las trataría como constantes y MySQL las convertirá implícitamente en fechas.

+0

¡Muchas gracias! Después de su respuesta, ingresé al código fuente de Grails y lo encontré para ejecutar consultas HQL: Account.executeQuery ("seleccione un número distinto de la cuenta a donde a.branch =: branch ", [branch: 'London']) Así que hice lo mismo para mi situación y funcionó. Thx. – fabien7474

5

Me señalado por ChssPly, debe declarar date1 y date2 como parámetros de consulta (posicional o nombre) y luego atarlos. Aquí, usaremos parámetros nombrados. 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]) 

Comprobar executeQuery() documentación para los detalles de sintaxis de ambas opciones.

+0

Hola Pascal Gracias por tu ayuda. Hice exactamente lo que has escrito. – fabien7474

3

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. Solo recuerda envolver las fechas como una cadena.

Cuestiones relacionadas