Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Hibernar Oracle INTERVAL EXPRESSION e Oracle 11g Dialect


Depois de 2 dias sofrendo, analisando o processamento AST do código fonte de hibernação eu finalmente desisti!! =P .. Na verdade ainda não existe um Oracle 11g Dialect disponível.

Então, mudei a estratégia e resolvo com as seguintes alterações:

1. Crie a função follow no banco de dados 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;

DICA DETERMINÍSTICA na função é muito importante para evitar problemas de desempenho ao usá-la em Where-Clauses. Mais informações sobre isso no link:http://www.inside-oracle-apex.com/caution-when-using-plsql-functions-in-sql-statement/

2. Crie uma classe de dialeto Oracle personalizada e registre a nova função.
public class Oracle11gDialectExtended extends Oracle10gDialect {

    public Oracle11gDialectExtended() {

        super();

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

    }
}

Então, basta chamá-lo em @Formula :
@Formula(" INTERVAL_HOURS_AGO( SHOW_LIMIT_HOURS ) ")
private Date showLimitDate;

Ou em HQL/NamedQuery:
select p from Product p 
  where p.createdAt > interval_hours_ago(60)