This proposal suggests adding support using [EL expressions] (http://docs.oracle.com/javaee/7/tutorial/doc/jsf-el002.htm) in JPA query strings. With this one could define query string templates and dynamic parameter bindings based on EL (Expression Language).
-
Immediate evaluation (via ${...}) could be used to statically alter the query string in cases where the user wants to statically generate a fixed part of a query. This could be used to add query fragments or adjust the name of tables or columns / fields.
-
Deferred evaluation (via #{...}) could be used to dynamically compute a parameter value in cases where the user wants to avoid having to compute and set the parameter values explicitly.
##Example 1: The JPA-QL query:
{code:sql}
select o from BusinessObject o where o.owner.emailAddress like ?#{ hasRole('ROLE_ADMIN') ? '%' : principal.emailAddress}
{code}
would translate to:
{code:sql}
select o from BusinessObject o where o.owner.emailAddress like ?1
{code}
With ?1 bound to the result of the dynamically evaluated EL expression "hasRole('ROLE_ADMIN') ? '%' : principal.emailAddress". The parameter ?1 would be dynamically registered.
The JPA-QL query:
{code:sql}
select o from BusinessObject o where o.owner.emailAddress = ?1 ${ currentTenant != null ? ' and o.tenant = ?#{' + currentTenant.id + '}' : ''}
{code}
would translate to either:
{code:sql}
select o from BusinessObject o where o.owner.emailAddress = ?1
{code}
or:
{code:sql}
select o from BusinessObject o where o.owner.emailAddress = ?1 and o.tenant = ?2
{code}
where ?2 is bound to the result of the dynamically evaluated expression "currentTenant.id".
It would be helpful to have some kind of SPI at the EntityManagerFactory that allows libraries or users to customize the EL expression context somehow, e.g. by allowing to expose functions, properties, variables and the like.
As an extension one could also allow to bind parameter values of type 'javax.el.Expression' to every exposed parameter of a JPA query. The value to be bound could then derived at query time by evaluating the given expression.
We implemented that feature in the latest version of the Spring Data JPA Repository abstraction. https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions