我可以在Hibernate自定义方言中嵌套函数吗?

时间:2013-06-28 16:01:57

标签: hibernate hql

我有一个需要支持多个数据库(MySQL,Oracle,Sybase等)的hibernate模型,并且里面有一些日期逻辑。浏览各种论坛/帖子我遇到了为Hibernate创建自定义方言并注册函数的想法,每个方言都有特定于数据库的逻辑。这些工作很精彩(只显示相关的部分 - 提前道歉,我不得不混淆帖子的一些值和字段名称):

public MyOracle10gDialect() {
    super();
    SQLFunctionTemplate sqlFunctionTemplate = 
            new SQLFunctionTemplate(Hibernate.DATE, "SYSDATE - ?1");

    registerFunction("date_sub_days", sqlFunctionTemplate);
}

public MyMySQLDialect() {
    super();
    SQLFunctionTemplate sqlFunctionTemplate = 
            new SQLFunctionTemplate(Hibernate.DATE, "DATE_SUB(UTC_TIMESTAMP(),INTERVAL ?1 DAY)");
    registerFunction("date_sub_days", sqlFunctionTemplate);
}

现在我需要使用一个函数来解析传递给这个函数的参数。不幸的是我无法访问使用此模型的代码,否则我只是将逻辑移动到代码中,但有没有办法做嵌套函数?我想使用'GREATEST(x,y,z)'作为我的'date_sub_days'函数的参数。我基本上希望这个工作并且失败了:

WHERE date_sub_days(GREATEST(:TRADE_HISTORY_MAX_DAYS,:ORDER_HISTORY_MAX_DAYS,:NEG_HISTORY_MAX_DAYS)) < value1

因为它没有将“最大”函数解析为单个参数。

在MySQL中,我将以下内容打印到控制台:

Hibernate: 
select blah from blah where
    DATE_SUB(UTC_TIMESTAMP(),INTERVAL GREATEST(? DAY) < value1 
ERROR util.JDBCExceptionReporter - Parameter index out of range (2 > number of parameters, which is 1).

在Oracle中,我将以下内容打印到控制台:

Hibernate: 
select blah from blah where 
SYSDATE - GREATEST(?<value1
ERROR util.JDBCExceptionReporter - Invalid column index

很想听听有关如何在方言或HQL中进行更改的建议。

1 个答案:

答案 0 :(得分:0)

我找不到让嵌套函数工作的方法,但我确实提出了一个非常简单的解决方法。它缺乏我所针对的代码重用(所以必须对所有函数进行任何更改)但至少它允许我继续使用自定义方言。

而不是试图嵌套函数:

WHERE date_sub_days(GREATEST(:TRADE_HISTORY_MAX_DAYS,:ORDER_HISTORY_MAX_DAYS,:NEG_HISTORY_MAX_DAYS))

我创建了一个单独的函数,其中包含更多参数:

WHERE date_sub_days_greatest(:TRADE_HISTORY_MAX_DAYS,:ORDER_HISTORY_MAX_DAYS,:NEG_HISTORY_MAX_DAYS)

并在方言级别嵌套逻辑:

SQLFunctionTemplate dateSubDaysFunction = new SQLFunctionTemplate(Hibernate.DATE, "SYSDATE - ?1");
registerFunction("date_sub_days", dateSubDaysFunction);

SQLFunctionTemplate dateSubDaysGreatestFunction = new SQLFunctionTemplate(Hibernate.DATE, "SYSDATE - GREATEST(?1,?2,?3)");
registerFunction("date_sub_days_greatest", dateSubDaysGreatestFunction);

希望能帮助其他人!