Hibernate Oracle INTERVAL EXPRESSION 和 Oracle 11g 方言

Hibernate Oracle INTERVAL EXPRESSION and Oracle 11g Dialect

我需要对计算字段使用 INTERVAL EXPRESSION。如下所示:

@Formula(" SYSDATE - INTERVAL '1' HOUR * SHOW_LIMIT_HOURS ")
private Date showLimitDate;

但是,hibernate 会生成以下 SQL 片段,将此表达式视为列。

and product0_.sold_at > (
                SYSDATE - settings0_.INTERVAL '1' settings0_.HOUR * setting0_.SHOW_LIMIT_HOURS
            )

有人可以帮助我吗?

折腾了2天,分析hibernate源码的AST处理终于放弃了!! =P .. 实际上还没有可用的 Oracle 11g 方言。

所以,我改变了策略并通过以下更改解决了它:

1.在 Oracle 数据库上创建跟随函数

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;

函数的确定性提示对于避免在 Where-Clauses 上使用时出现性能问题非常重要。 link 上的更多信息: http://www.inside-oracle-apex.com/caution-when-using-plsql-functions-in-sql-statement/

2。创建自定义 Oracle 方言 Class 并注册新函数。

public class Oracle11gDialectExtended extends Oracle10gDialect {

    public Oracle11gDialectExtended() {

        super();

       registerFunction("interval_hours_ago", 
           new StandardSQLFunction("INTERVAL_HOURS_AGO", StandardBasicTypes.DATE));

    }
}

所以,只需在@Formula 上调用它即可:

@Formula(" INTERVAL_HOURS_AGO( SHOW_LIMIT_HOURS ) ")
private Date showLimitDate;

或在 HQL/NamedQuery 上:

select p from Product p 
  where p.createdAt > interval_hours_ago(60)