Hibernate Oracle INTERVAL EXPRESSION and Oracle 11g Dialect

随声附和 提交于 2019-12-24 17:24:49

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!