Дата операции в HQL

Я хочу получить истекшие сущности из таблицы с помощью HQL. Что-то вроде этого:--2-->

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

Я не могу понять, как это сделать с HQL. Я не хочу делать дополнительные запросы, обрабатывать дату в java-коде и так далее. Это должно быть сделано на уровне HQL.

Не могли бы вы мне помочь?

2 ответов


в зависимости от вашей базы данных, это может быть тривиально простым. HQL поддерживает встроенные функции и функции, специфичные для поставщика, а также поддерживает возможность расширения диалекта путем регистрации новых функций, если они еще не поддерживаются HQL.

предположим, вы используете SQLServer (или Sybase). SQLServer имеет функцию под названием "DATEADD", которая может делать то, что вам нравится, очень легко. Формат:

DATEADD (datepart, number, date)

вы можете использовать эту функцию непосредственно в HQL сначала Регистрация функции на вашем собственном диалекте Hibernate. Для этого вам просто нужно расширить диалект, который вы используете в настоящее время. Это очень простой процесс.

сначала создайте свой собственный класс диалекта (замените "SQLServer2008Dialect" на свой собственный поставщик БД):

public class MySQLServerDialect extends SQLServer2008Dialect {

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

}

затем измените конфигурацию hibernate, чтобы использовать этот новый класс:

<?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>

теперь просто используйте функцию:

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

(предполагается, что ваша сущность называется MyEntity и поле creation_date сопоставляется со свойством creationDate).


HQL не поддерживает арифметику с датой и временем, поэтому это невозможно без расширения HQL. Самый простой путь-это, вероятно, зарегистрировать функцию SQL dialect поставщиков баз данных для такого расчета. Другая возможность реализовать и зарегистрировать перехватчик (метод переопределения onPrepareStatement), Если синтаксис со знаками плюс и минус является предпочтительным.

когда решение не должно быть чисто в HQL и время от хоста JVM достаточно простое решение вычислите дату, которая составляет 10 минут в прошлом, и дайте ее в качестве аргумента. Если время базы данных предпочтительнее, это может быть достигнуто путем запроса его в отдельном запросе, а затем уменьшения 10 минут от него.