Cómo hacer una marca de hora comparación con JPA consulta?
Pregunta
Necesitamos asegurarnos de que sólo los resultados en los últimos 30 días son devueltos por una consulta JPQL.Un ejemplo es el siguiente:
Date now = new Date();
Timestamp thirtyDaysAgo = new Timestamp(now.getTime() - 86400000*30);
Query query = em.createQuery(
"SELECT msg FROM Message msg "+
"WHERE msg.targetTime < CURRENT_TIMESTAMP AND msg.targetTime > {ts, '"+thirtyDaysAgo+"'}");
List result = query.getResultList();
Aquí está el error que recibimos:
<openjpa-1.2.3-SNAPSHOT-r422266:907835 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: An error occurred while parsing the query filter 'SELECT msg FROM BroadcastMessage msg WHERE msg.targetTime < CURRENT_TIMESTAMP AND msg.targetTime > {ts, '2010-04-18 04:15:37.827'}'. Error message: org.apache.openjpa.kernel.jpql.TokenMgrError: Lexical error at line 1, column 217. Encountered: "{" (123), after : ""
Ayuda!
Solución
Por lo que la consulta que la entrada no es JPQL (que se podía ver, al referirse a la especificación JPA).Si quieres comparar un campo con una Fecha de entrada de la Fecha como un parámetro a la consulta
msg.targetTime < CURRENT_TIMESTAMP AND msg.targetTime > :param
ESTO NO ES SQL.
Otros consejos
La sintaxis de escape JDBC puede no ser compatible con la versión de OpenJPA que está utilizando. La documentación de la última versión 1.2.x está aquí: http://openjpa.apache.org/builds/1.2.2/apache-openjpa-1.2.2/docs/manual/manual.html#jpa_langref_lit .
La documentación se ha mencionado anteriormente se refiere a la documentación para OpenJPA 2.0.0 (última): http://openjpa.apache.org/builds/latest/docs/manual/jpa_langref.html#jpa_langref_lit
Dicho esto ¿hay alguna razón por la que desea inyectar una cadena en su JPQL? ¿Qué pasa con algo como el siguiente fragmento de código?
Date now = new Date();
Date thirtyDaysAgo = new Date(now.getTime() - (30 * MS_IN_DAY));
Query q = em.createQuery("Select m from Message m "
+ "where m.targetTime < :now and m.targetTime > :thirtyDays");
q.setParameter("now", now);
q.setParameter("thirtyDays", thirtyDaysAgo);
List<Message> results = (List<Message>) q.getResultList();