Pregunta Fecha de operaciones en HQL


Quiero obtener entidades expiradas de la tabla usando HQL. Algo como eso:

select id, name from entity_table where date_creation + 10_minutes < current_time()

No puedo entender cómo hacerlo con HQL. NO QUIERO hacer consultas adicionales, procesar la fecha en código java, etc. Esto debe hacerse en el nivel HQL.

¿Podrías ayudarme?


8
2017-11-26 16:25


origen


Respuestas:


Dependiendo de su base de datos, esto puede ser trivialmente simple. HQL admite funciones y funciones integradas específicas del proveedor, también admite la capacidad de ampliar el dialecto registrando nuevas funciones si HQL aún no lo admite.

Digamos que estás usando SQLServer (o Sybase). SQLServer tiene una función llamada 'DATEADD' que puede hacer lo que quiera con mucha facilidad. El formato es:

DATEADD (datepart, number, date)

Puede usar esta función directamente en HQL registrando primero la función en su propio Hibernate Dialect. Para hacer esto, solo tienes que extender el Dialecto que estás usando actualmente. Este es un proceso muy simple.

Primero, cree su propia clase de dialecto (reemplace 'SQLServer2008Dialect' con su propio proveedor de DB):

public class MySQLServerDialect extends SQLServer2008Dialect {

  public MySQLServerDialect() {
    registerFunction("addminutes", new VarArgsSQLFunction(TimestampType.INSTANCE, "dateadd(minute,", ",", ")"));
  }

}

Luego, modifique su configuración de hibernación para usar esta nueva clase:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    ...
    <property name="hibernate.dialect">com.mycompany.MySQLServerDialect</property>
    ...
</hibernate-configuration>

Ahora simplemente usa la función:

select x from MyEntity x where addminutes(x.creationDate, 10) < current_time()

(Esto supone que su entidad se llama MyEntity y el campo creation_date está mapeado a una propiedad llamada creationDate).


10
2017-11-26 21:49



HQL no admite aritmética con fecha y hora, por lo que no es posible sin extender HQL. La ruta más fácil es, probablemente, registrar proveedores de base de datos función dialecto SQL para dicho cálculo. Otra posibilidad es implementar y registrar interceptador (método para anular es onPrepareStatement), si se prefiere la sintaxis con signos más y menos.

Cuando la solución no tiene que ser puramente en HQL y el tiempo desde el host de JVM es suficiente, la solución más fácil es calcular la fecha de 10 minutos pasados ​​y darla como argumento. Si se prefiere el tiempo de la base de datos, eso se puede lograr al consultarlo en una consulta por separado y luego reducirlo en 10 minutos.


3
2017-11-26 20:25