Добавление дней к именованному параметру типа Date в HQL - PullRequest
3 голосов
/ 24 мая 2011

У меня есть база данных оракула, в которой хранятся склады, которые открыты только один день в неделю, например, «понедельник» или «четверг».

День открытия склада сохраняется как целое число.Воскресенье хранится как 0, суббота - 6. Каждый склад открыт только в течение определенного периода времени, известного как период его действия.Этот период действия хранится в виде двух дат: даты начала действия и даты окончания действия.Например, склад открыт в течение двух месяцев с 01-01-2011 до 28-02-2011.

Теперь я хочу выбрать все действующие склады на данную неделю.Запрошенная неделя считается датой.Принято считать, что этой датой всегда будет какое-то воскресенье, например, 29 мая 2011 года. Это приводит к следующему запросу:

  from Warehouse w
 where (:requested_week_date + w.day_open) between w.valid_start and w.valid_end

Проблема в том, что этот запрос даст исключение приведения класса:

java.lang.ClassCastException: java.util.Date incompatible with java.lang.Integer

Дело в том, что под водой Oracle способен добавлять целое число к дате.Oracle будет рассматривать целое число как число дней, добавляемых к дате.У меня вопрос: возможно ли заставить это работать в HQL .

Я знаю, что вы также можете определить собственные SQL-запросы в Hibernate (уже пробовал это, и это работает хорошо), но этоэто не ответ, который я ищу.Я просто ищу решение HQL, учитывая, что оно есть.

1 Ответ

4 голосов
/ 24 мая 2011

Решением может быть подкласс используемого вами оракула и регистрация дополнительной функции add_days, которая будет выполнять соответствующий перевод SQL:

package foo.bar;

import org.hibernate.dialect.Oracle10gDialect;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.type.StandardBasicTypes;

public class MyOracleDialect extends Oracle10gDialect {
    @Override
    protected void registerFunctions() {
        super.registerFunctions();
        registerFunction("add_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "(?1 + ?2)"));
    }
}

Теперь, когда класс диалекта определен, используйте этот класс в своей конфигурации гибернации:

hibernate.dialect=foo.bar.MyOracleDialect

И используйте следующий HQL-запрос:

from Warehouse w
  where add_days(:requested_week_date, w.day_open) between w.valid_start and w.valid_end
...