问题
I need to use a INTERVAL EXPRESSION for a calculated field. like below:
@Formula(" SYSDATE - INTERVAL '1' HOUR * SHOW_LIMIT_HOURS ")
private Date showLimitDate;
However, hibernate produces the following SQL fragment considering this expression like a column.
and product0_.sold_at > (
SYSDATE - settings0_.INTERVAL '1' settings0_.HOUR * setting0_.SHOW_LIMIT_HOURS
)
Anybody could help me ?
回答1:
After 2 days suffering, analysing AST processing of hibernate source code i finally gave up !! =P .. In fact there isnt a Oracle 11g Dialect available yet.
So , I changed the strategy and solve it with following changes :
1. Create the follow function on Oracle database
CREATE OR REPLACE FUNCTION INTERVAL_HOURS_AGO(HOURS_PARAM IN NUMBER)
RETURN DATE DETERMINISTIC
IS TIME_AGO DATE;
BEGIN
SELECT (SYSDATE - INTERVAL '1' HOUR * HOURS_PARAM) INTO TIME_AGO FROM DUAL;
RETURN(TIME_AGO);
END;
DETERMINISTIC HINT on function is very important for avoid performance issue when use it on Where-Clauses. More infos about it on link: http://www.inside-oracle-apex.com/caution-when-using-plsql-functions-in-sql-statement/
2. Create a Custom Oracle Dialect Class And Register the new Function.
public class Oracle11gDialectExtended extends Oracle10gDialect {
public Oracle11gDialectExtended() {
super();
registerFunction("interval_hours_ago",
new StandardSQLFunction("INTERVAL_HOURS_AGO", StandardBasicTypes.DATE));
}
}
So, just call it on @Formula :
@Formula(" INTERVAL_HOURS_AGO( SHOW_LIMIT_HOURS ) ")
private Date showLimitDate;
Or on HQL / NamedQuery :
select p from Product p
where p.createdAt > interval_hours_ago(60)
来源:https://stackoverflow.com/questions/32013169/hibernate-oracle-interval-expression-and-oracle-11g-dialect