2010-05-18 14 views
20
SELECT x FROM SomeClass 
WHERE x.dateAtt BETWEEN CURRENT_DATE AND (CURRENT_DATE + 1 MONTH) 

En la declaración JPQL anterior, SomeClass tiene una memebr dateAttr, que es un java.util.Date y tiene una anotación @Temporal(javax.persistence.TemporalType.DATE).Java: función de la fecha JPQL añadir un período de tiempo para otra fecha

Necesito una forma de hacer el bit (CURRENT_DATE + 1 MONTH) - obviamente está mal en su estado actual - pero no puedo encontrar el documento con la función de fecha para JPQL.

¿Alguien me puede indicar en un documento que documenta las funciones de fecha JPQL (y también cómo hacer esta consulta en particular)?

+0

¿Es esta una consulta en algún método que desee? ¿O necesita esto estar en un disparador en la entidad bean self? IE: '@ PrePersist' o' @ PreUpdate'? –

+0

@Shervin: No, la consulta no necesita realizarse en '@ PrePersist' o' @ PreUpdate'. La consulta es una consulta con nombre en una clase de entidad JPA ('SomeClass'). – bguiz

+0

@Shervin: Además, sé que puedo usar Java para calcular las manipulaciones 'Fecha' y luego pasarlo a la consulta usando': parameter', sin embargo, preferiría hacerlo en el JPQL mismo y evitar eso innecesario código. – bguiz

Respuesta

17

Si usted tiene un objeto fecha que es + 1 mes de que ya se podía hacer algo como esto:

public List findEmployees(Date endDate) { 
    return entityManager.createQuery(
    "SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2") 
    .setParameter(1,new Date(), TemporalType.DATE) 
    .setParameter(2,endDate, TemporalType.DATE).getResultList(); 
} 
embargo

Esto, requiere que las fechas sean válidas antes de la mano.

ACTUALIZACIÓN

Si siempre quiere que el próximo mes, puede utilizar JodaTime que tiene una gran y fácil api. A continuación, podría modificar su consulta como esta:

//Get next month 
DateTime dt = new DateTime(); 
entityManager.createQuery(
"SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2") 
.setParameter(1,new Date(), TemporalType.DATE) 
.setParameter(2,dt.plusMonths(1).toDate(), TemporalType.DATE).getResultList(); 
+3

¿Has probado la parte JodaTime? ¿Puede JPA lidiar con un 'DateTime'? –

+0

@Pascal: Buen punto.Olvidé el método toDate() Esto devolverá un 'java.util.Date' –

+1

Mejora leve:' .setParameter (1, dt.toDate(), TemporalType.DATE) '(una importación menos y consistencia con la siguiente línea) –

4

O utilizar commons-lang en lugar de JodaTime:

entityManager.createQuery(
    "SELECT e from Employee e WHERE e.startDate BETWEEN ?1 AND ?2" 
) 
.setParameter(1,new Date(), TemporalType.DATE) 
.setParameter(2,DateUtils.addMonths(new Date(), 1), TemporalType.DATE) 
.getResultList(); 

Pero sé que esto no es lo que están pidiendo y estoy bastante seguro de que no se puede hacer solo en JPQL, tendrá que pasar un parámetro o utilizar una consulta con nombre nativo

+0

'DateUtils'? ¿Es eso parte de std JDK o es una biblioteca como Joda time? – bguiz

+0

está en apache commons/lang, una biblioteca de código abierto que se usa internamente en muchos marcos: http://commons.apache.org/lang/ –

+2

Es mejor utilizar Joda-Time porque es una implementación de referencia de JSR-310 (https : //jsr-310.dev.java.net/) –

15

El estándar JPQL no admite tales operaciones en las fechas. Deberá usar una consulta nativa o hacer el cálculo en el lado de Java.

+1

¿Sigue siendo cierto? – span

0

queridos,

estoy usando datos de primavera, la entidad guardar el CreatedDate como fecha y hora, y en el repositorio de la siguiente manera:

@Query(value="SELECT t FROM MyEntity t WHERE t.createdDate Between ?1 and ?2") 
public List<MyEntity> findAllBetweenDates(Calendar from, Calendar to); 

así que no puedo usar:

setParameter(1,new Date(), TemporalType.DATE 

en el grano backend i utilizar lo siguiente:

//to set zero of hours,minutes,seconds and milliseconds 
    fromCalendar.set(java.util.Calendar.HOUR, 0); 
    fromCalendar.set(java.util.Calendar.MINUTE, 0); 
    fromCalendar.set(java.util.Calendar.SECOND, 0); 
    fromCalendar.set(java.util.Calendar.MILLISECOND, 0); 

    toCalendar.set(java.util.Calendar.HOUR, 0); 
    toCalendar.set(java.util.Calendar.MINUTE, 0); 
    toCalendar.set(java.util.Calendar.SECOND, 0); 
    toCalendar.set(java.util.Calendar.MILLISECOND, 0); 
    // add 1 days and decrease 1 millisecond 
    toCalendar.add(java.util.Calendar.DAY_OF_MONTH, 1); 
    toCalendar.add(java.util.Calendar.MILLISECOND, -1); 

    allEntities = myEntityRepository.findAllBetweenDates(fromCalendar, toCalendar); 
} 

y funciona bien.

Cuestiones relacionadas