Lo sviluppo web (e non solo) oggi non può fare a meno di alcune componenti fondamentali ed una di queste è sicuramente un ORM (Object Relational Mapping) che gestisca la persistenza degli oggetti in modo veloce ed efficiente. La nostra scelta è, da ormai 3 anni, quella di utilizzare EclipseLink e di creare NamedQuery nel relativo linguaggio JPQL. Vediamo in questo post un aspetto del linguaggio JPQL che ci consente di usare funzionalità proprietarie di un RDBMS sottostante, come ad esempio Oracle 11g.
Prima o poi a tutti sarà capitato di dover scrivere una query per il confronto fra date, e di voler escludere dal controllo la porzione tempo. Esempio classico è cercare fra tutti i record quelli modificati in un dato giorno.
Supponiamo di avere una tabella MYTABLE con tre campi:
- ID
- UPDATED_TIMESTAMP
- RECORD_NAME
e di voler estrarre tutti quelli modificati nel giorno corrente. La query più semplice e immediata prevede l’utilizzo della funzione TRUNC come riportato sotto:
SELECT * FROM MYTABLE where TRUNC(SYSDATE) = TRUNC(UPDATED_TIMESTAMP);
Tradotta in JPQL questa query però non viene compilata per Persistence Manager perchè l’operatore TRUNC non esiste in JPQL, essendo infatti una prerogativa del RDBMS Oracle.
JPQL, operatore FUNC (o FUNCTION)
Per risolvere questo problema (e non solo questo) ci viene in aiuto l’operatore FUNC, che permette di effettuare chiamate arbitrarie a funzioni identificate tramite stringhe che corrispondono alla loro sintassi nel linguaggio SQL originale.
In questo caso la query diventa quindi:
@NamedQuery(name = "MyTable.findModifiedToday", query = "SELECT r FROM MyTable r WHERE FUNC('TRUNC',CURRENT_TIMESTAMP) = FUNC('TRUNC',r.updatedTimestamp)")
Lo stesso vale per qualsiasi altra funzione, come evidenziato dalla documentazione ufficiale di EclipseLink.