Oracle
 sql >> Database >  >> RDS >> Oracle

Ibernazione Oracle INTERVAL EXPRESSION e Oracle 11g Dialect

Dopo 2 giorni di sofferenza, analizzando l'elaborazione AST del codice sorgente di ibernazione, alla fine ho rinunciato !! =P .. In realtà non è ancora disponibile un Oracle 11g Dialect.

Quindi, ho cambiato la strategia e l'ho risolto con le seguenti modifiche:

1. Crea la funzione follow sul database 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;

SUGGERIMENTO DETERMINISTICO sulla funzione è molto importante per evitare problemi di prestazioni quando lo si utilizza su Where-Clauses. Maggiori informazioni a riguardo sul link:http://www.inside-oracle-apex.com/caution-when-using-plsql-functions-in-sql-statement/

2. Crea una classe di dialetto Oracle personalizzata e registra la nuova funzione.

public class Oracle11gDialectExtended extends Oracle10gDialect {

    public Oracle11gDialectExtended() {

        super();

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

    }
}

Quindi, chiamalo su @Formula :

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

Oppure su HQL / NamedQuery :

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