blob: 5c438f852ffbb80e362e62207e3b42a48f844c11 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<chapter id="jpa_overview_query">
<title>
JPA Query
</title>
<indexterm zone="jpa_overview_query">
<primary>
JP Query
</primary>
<seealso>
JPQL
</seealso>
</indexterm>
<indexterm>
<primary>
queries
</primary>
<see>
Query
</see>
</indexterm>
<mediaobject>
<imageobject>
<!-- PNG image data, 292 x 265 (see README) -->
<imagedata fileref="img/jpa-query.png" width="195px"/>
</imageobject>
</mediaobject>
<para>
The <classname>javax.persistence.Query</classname> interface is the mechanism
for issuing queries in JPA. The primary query language used is the Java
Persistence Query Language, or <literal>JPQL</literal>. JPQL is syntactically
very similar to SQL, but is object-oriented rather than table-oriented.
</para>
<para>
The API for executing JPQL queries will be discussed in
<xref linkend="jpa_query_api"/>, and a full language reference will be
covered in <xref linkend="jpa_langref"/>.
</para>
<section id="jpa_query_api">
<title>
JPQL API
</title>
<section id="jpa_overview_query_basic">
<title>
Query Basics
</title>
<programlisting>SELECT x FROM Magazine x
</programlisting>
<para>
The preceding is a simple JPQL query for all <classname>Magazine</classname>
entities.
</para>
<programlisting>
public Query createQuery(String jpql);
</programlisting>
<para>
The
<ulink url="http://download.oracle.com/javaee/6/api/javax/persistence/EntityManager.html">
<methodname>EntityManager.createQuery</methodname></ulink> method creates a
<classname>Query</classname> instance from a given JPQL string.
</para>
<programlisting>
public List getResultList();
</programlisting>
<para>
Invoking
<ulink url="http://download.oracle.com/javaee/6/api/javax/persistence/Query.html#getResultList()">
<methodname>Query.getResultList</methodname></ulink> executes the query and
returns a <classname>List</classname> containing the matching objects. The
following example executes our <classname>Magazine</classname> query above:
</para>
<programlisting>
EntityManager em = ...
Query q = em.createQuery("SELECT x FROM Magazine x");
List&lt;Magazine&gt; results = (List&lt;Magazine&gt;) q.getResultList();
</programlisting>
<para>
A JPQL query has an internal namespace declared in the <literal>from</literal>
clause of the query. Arbitrary identifiers are assigned to entities so that they
can be referenced elsewhere in the query. In the query example above, the
identifier <literal>x</literal> is assigned to the entity <classname> Magazine
</classname>.
</para>
<note>
<para>
The <literal>as</literal> keyword can optionally be used when declaring
identifiers in the <literal>from</literal> clause. <literal>SELECT x FROM
Magazine x</literal> and <literal>SELECT x FROM Magazine AS x</literal> are
synonymous.
</para>
</note>
<para>
Following the <literal>select</literal> clause of the query is the object or
objects that the query returns. In the case of the query above, the query's
result list will contain instances of the <classname>Magazine</classname> class.
</para>
<note>
<para>
When selecting entities, you can optionally use the keyword <literal>object
</literal>. The clauses <literal>select x</literal> and <literal>SELECT
OBJECT(x)</literal> are synonymous.
</para>
</note>
<para>
The optional <literal>where</literal> clause places criteria on matching
results. For example:
</para>
<programlisting>SELECT x FROM Magazine x WHERE x.title = 'JDJ'</programlisting>
<para>
Keywords in JPQL expressions are case-insensitive, but entity, identifier, and
member names are not. For example, the expression above could also be expressed
as:
</para>
<programlisting>select x from Magazine x where x.title = 'JDJ'</programlisting>
<para>
But it could not be expressed as:
</para>
<programlisting>SELECT x FROM Magazine x WHERE x.TITLE = 'JDJ'</programlisting>
<para>
As with the <literal>select</literal> clause, alias names in the <literal>where
</literal> clause are resolved to the entity declared in the <literal>from
</literal> clause. The query above could be described in English as "for all
<classname>Magazine</classname> instances <literal>x</literal>, return a list
of every <literal>x</literal> such that <literal>x</literal>'s <literal>title
</literal> field is equal to 'JDJ'".
</para>
<para>
JPQL uses SQL-like syntax for query criteria. The <literal>and</literal> and
<literal>or</literal> logical operators chain multiple criteria together:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.title = 'JDJ' OR x.title = 'JavaPro'
</programlisting>
<para>
The <literal>=</literal> operator tests for equality. <literal>&lt;&gt;
</literal> tests for inequality. JPQL also supports the following arithmetic
operators for numeric comparisons: <literal>&gt;, &gt;=, &lt;, &lt;=</literal>.
For example:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.price &gt; 3.00 AND x.price &lt;= 5.00
</programlisting>
<para>
This query returns all magazines whose price is greater than 3.00 and less than
or equal to 5.00.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.price &lt;&gt; 3.00
</programlisting>
<para>
This query returns all Magazines whose price is not equal to 3.00.
</para>
<para>
You can group expressions together using parentheses in order to specify how
they are evaluated. This is similar to how parentheses are used in Java. For
example:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE (x.price &gt; 3.00 AND x.price &lt;= 5.00) OR x.price &lt; 7.00
</programlisting>
<para>
This expression would match magazines whose price is less than 7.00.
Alternately:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.price &gt; 3.00 AND (x.price &lt;= 5.00 OR x.price &lt; 7.00)
</programlisting>
<para>
This expression would match magazines whose price is 4.00, 5.00 or 6.00, but not
1.00, 2.00 or 3.00.
</para>
<para>
JPQL also includes the following conditionals:
</para>
<itemizedlist>
<listitem>
<para>
<indexterm>
<primary>
BETWEEN expressions
</primary>
</indexterm>
<literal>[NOT] BETWEEN</literal>: Shorthand for expressing that a value falls
between two other values. The following two statements are synonymous:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.price &gt;= 3.00 AND x.price &lt;= 5.00
</programlisting>
<programlisting>
SELECT x FROM Magazine x WHERE x.price BETWEEN 3.00 AND 5.00
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
LIKE expressions
</primary>
</indexterm>
<literal>[NOT] LIKE</literal>: Performs a string comparison with wildcard
support. The special character '_' in the parameter means to match any single
character, and the special character '%' means to match any sequence of
characters. The following statement matches title fields "JDJ" and "JavaPro",
but not "IT Insider":
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.title LIKE 'J%'
</programlisting>
<para>
The following statement matches the title field "JDJ" but not "JavaPro":
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.title LIKE 'J__'
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
IN expressions
</primary>
</indexterm>
<literal>[NOT] IN</literal>: Specifies that the member must be equal to one
element of the provided list. The following two statements are synonymous:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.title IN ('JDJ', 'JavaPro', 'IT Insider')
</programlisting>
<programlisting>SELECT x FROM Magazine x WHERE x.title = 'JDJ' OR x.title = 'JavaPro' OR x.title = 'IT Insider'
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
IS EMPTY expressions
</primary>
</indexterm>
<literal>IS [NOT] EMPTY</literal>: Specifies that the collection field holds no
elements. For example:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.articles is empty
</programlisting>
<para>
This statement will return all magazines whose <literal> articles</literal>
member contains no elements.
</para>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
IS NULL expressions
</primary>
</indexterm>
<literal>IS [NOT] NULL</literal>: Specifies that the field is equal to null.
For example:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.publisher is null
</programlisting>
<para>
This statement will return all Magazine instances whose "publisher" field is set
to <literal>null</literal>.
</para>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
NOT expressions
</primary>
</indexterm>
<literal>NOT</literal>: Negates the contained expression. For example, the
following two statements are synonymous:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE NOT(x.price = 10.0)
</programlisting>
<programlisting>
SELECT x FROM Magazine x WHERE x.price &lt;&gt; 10.0
</programlisting>
</listitem>
</itemizedlist>
</section>
<section id="jpa_overview_query_relations">
<title>
Relation Traversal
</title>
<para>
Relations between objects can be traversed using Java-like syntax. For example,
if the Magazine class has a field named "publisher" of type Company, that
relation can be queried as follows:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.publisher.name = 'Random House'
</programlisting>
<para>
This query returns all <classname>Magazine</classname> instances whose <literal>
publisher</literal> field is set to a <classname>Company</classname> instance
whose name is "Random House".
</para>
<para>
Single-valued relation traversal implies that the relation is not null. In SQL
terms, this is known as an <emphasis>inner join</emphasis>. If you want to also
include relations that are null, you can specify:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE x.publisher.name = 'Random House' or x.publisher is null
</programlisting>
<para>
You can also traverse collection fields in queries, but you must declare each
traversal in the <literal>from</literal> clause. Consider:
</para>
<programlisting>
SELECT x FROM Magazine x, IN(x.articles) y WHERE y.authorName = 'John Doe'
</programlisting>
<para>
This query says that for each <classname>Magazine</classname><literal> x
</literal>, traverse the <literal>articles</literal> relation and check each
<classname>Article</classname> <literal>y</literal>, and pass the filter if
<literal>y</literal>'s <literal>authorName</literal> field is equal to "John
Doe". In short, this query will return all magazines that have any articles
written by John Doe.
</para>
<note>
<para>
The <literal>IN()</literal> syntax can also be expressed with the keywords
<literal>inner join</literal>. The statements <literal>SELECT x FROM Magazine
x, IN(x.articles) y WHERE y.authorName = 'John Doe'</literal> and <literal>
SELECT x FROM Magazine x inner join x.articles y WHERE y.authorName = 'John Doe'
</literal> are synonymous.
</para>
</note>
</section>
<section id="jpa_overview_query_embeddables">
<title>
Embeddable Traversal
</title>
<para>
Similar to relation traversal, nested embeddable objects can be traversed using Java-like syntax.
For example, if the <classname>Company</classname> class has a field named "address" of
an embeddable type <classname>Address</classname>,
and the <classname>Address</classname> has a field named "geocode" of
an embeddable type <classname>Geocode</classname>,
the <literal>geocode</literal> of a company's address can be queried as follows:
</para>
<programlisting>
SELECT c.address.geocode FROM Company c WHERE c.name = 'Random House'
</programlisting>
<note>
<para>
The <literal>geocode</literal> returned by the above query will not be part of the state of any managed
entity. Modifications to these embeddable instances are not allowed.
</para>
</note>
<para>
Traversal into embeddable's state field is also allowed as shown in the following query:
</para>
<programlisting>
SELECT c.address.geocode.latitude FROM Company c WHERE c.name = 'Random House'
</programlisting>
<para>
Embeddable objects may contain single-valued or collection-valued relations.
These relations can also be traversed using Java-like syntax.
For example, if the Address has a relation field named "phoneLists" of
an entity type <classname>PhoneNumber</classname>,
the following query returns the <classname>PhoneNumber</classname> entities of the <classname>Company</classname>
named 'Random House':
</para>
<programlisting>
SELECT p FROM Company c, IN(c.address.phoneLists) p WHERE c.name = 'Random House'
</programlisting>
</section>
<section id="jpa_overview_join_fetch">
<title>
Fetch Joins
</title>
<para>
JPQL queries may specify one or more <literal>join fetch</literal> declarations,
which allow the query to specify which fields in the returned instances will be
pre-fetched.
</para>
<programlisting>
SELECT x FROM Magazine x join fetch x.articles WHERE x.title = 'JDJ'
</programlisting>
<para>
The query above returns <classname>Magazine</classname> instances and guarantees
that the <literal>articles</literal> field will already be fetched in the
returned instances.
</para>
<para>
Multiple fields may be specified in separate <literal>join fetch</literal>
declarations: <programlisting>
SELECT x FROM Magazine x join fetch x.articles join fetch x.authors WHERE x.title = 'JDJ'
</programlisting>
</para>
<para>
Notice that in the above query, both <literal>articles</literal> and <literal>authors</literal>
are relation property in <classname>Magazine</classname>.
JPQL syntax does not allow range variable declared for paths on the right-hand side of
<literal>join fetch</literal>.
Therefore, if <classname>Article</classname> entity has a relation property of
<literal>publishers</literal>,
it is not possible to specify a query
that returns <classname>Magazine</classname> instances and pre-fetch
the <literal>articles</literal> and the <literal>publishers</literal>.
The following query will result in syntax error:
<programlisting>
SELECT x FROM Magazine x join fetch x.articles a join fetch a.publishers p WHERE x.title = 'JDJ'
</programlisting>
</para>
<para>
<note><para> Specifying the <literal>join fetch</literal> declaration is
functionally equivalent to adding the fields to the Query's <classname>
FetchConfiguration</classname>. See <xref linkend="ref_guide_fetch"/>.
</para>
</note>
</para>
</section>
<section id="jpa_overview_query_functions">
<title>
JPQL Functions
</title>
<para>
As well as supporting direct field and relation comparisons, JPQL supports a
pre-defined set of functions that you can apply.
</para>
<itemizedlist>
<listitem>
<para>
<indexterm>
<primary>
CONCAT function
</primary>
</indexterm>
<literal>CONCAT(string1, string2)</literal>: Concatenates two string fields or
literals. For example:
</para>
<programlisting>
SELECT x FROM Magazine x WHERE CONCAT(x.title, 's') = 'JDJs'
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
SUBSTRING function
</primary>
</indexterm>
<literal>SUBSTRING(string, startIndex, [length])</literal>: Returns the part of
the <literal>string</literal> argument starting at <literal>startIndex</literal>
(1-based) and optionally ending at <literal>length</literal> characters past <literal>
startIndex</literal>. If the <literal>length</literal> argument is not specified,
the substring from the <literal>startIndex</literal> to the end of the <literal>string</literal>
is returned.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE SUBSTRING(x.title, 1, 1) = 'J'
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
TRIM function
</primary>
</indexterm>
<literal>TRIM([LEADING | TRAILING | BOTH] [character FROM] string</literal>:
Trims the specified character from either the beginning ( <literal>LEADING
</literal>) end ( <literal>TRAILING</literal>) or both ( <literal> BOTH
</literal>) of the string argument. If no trim character is specified, the
space character will be trimmed.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE TRIM(BOTH 'J' FROM x.title) = 'D'
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
LOWER function
</primary>
</indexterm>
<literal>LOWER(string)</literal>: Returns the lower-case of the specified
string argument.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE LOWER(x.title) = 'jdj'
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
UPPER function
</primary>
</indexterm>
<literal>UPPER(string)</literal>: Returns the upper-case of the specified
string argument.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE UPPER(x.title) = 'JAVAPRO'
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
LENGTH function
</primary>
</indexterm>
<literal>LENGTH(string)</literal>: Returns the number of characters in the
specified string argument.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE LENGTH(x.title) = 3
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
LOCATE function
</primary>
</indexterm>
<literal>LOCATE(searchString, candidateString [, startIndex])</literal>:
Returns the first index of <literal>searchString</literal> in <literal>
candidateString</literal>. Positions are 1-based. If the string is not found,
returns 0.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE LOCATE('D', x.title) = 2
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
ABS function
</primary>
</indexterm>
<literal>ABS(number)</literal>: Returns the absolute value of the argument.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE ABS(x.price) &gt;= 5.00
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
SQRT function
</primary>
</indexterm>
<literal>SQRT(number)</literal>: Returns the square root of the argument.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE SQRT(x.price) &gt;= 1.00
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
MOD function
</primary>
</indexterm>
<literal>MOD(number, divisor)</literal>: Returns the modulo of <literal>number
</literal> and <literal>divisor</literal>.
</para>
<programlisting>
SELECT x FROM Magazine x WHERE MOD(x.price, 10) = 0
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
INDEX function
</primary>
</indexterm>
<literal>INDEX(identification_variable)</literal>: Returns an integer value corresponding
to the position of its argument in an ordered list.
The INDEX function can only be applied to identification variables denoting types for
which an order column has been specified.
</para>
<para>
In the following example, <literal>studentWaitlist</literal> is a list of
students for which an order column has
been specified, the query returns the name of the first student on the waiting list of
the course named 'Calculus':
</para>
<programlisting>
SELECT w.name FROM Course c JOIN c.studentWaitlist w WHERE c.name = ‘Calculus’ AND INDEX(w) = 0
</programlisting>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
CURRENT_DATE function
</primary>
</indexterm>
<literal>CURRENT_DATE</literal>: Returns the current date.
</para>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
CURRENT_TIME function
</primary>
</indexterm>
<literal>CURRENT_TIME</literal>: Returns the current time.
</para>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
CURRENT_TIMESTAMP function
</primary>
</indexterm>
<literal>CURRENT_TIMESTAMP</literal>: Returns the current timestamp.
</para>
</listitem>
</itemizedlist>
</section>
<section id="jpa_overview_query_inheritance">
<title>
Polymorphic Queries
</title>
<para>
All JPQL queries are polymorphic, which means the <literal>from</literal> clause
of a query includes not only instances of the specific entity class to which it
refers, but all subclasses of that class as well. The instances returned by a
query include instances of the subclasses that satisfy the query conditions. For
example, the following query may return instances of <classname> Magazine
</classname>, as well as <classname>Tabloid</classname> and <classname>Digest
</classname> instances, where <classname>Tabloid</classname> and <classname>
Digest</classname> are <classname>Magazine</classname> subclasses.
</para>
<programlisting>SELECT x FROM Magazine x WHERE x.price &lt; 5</programlisting>
<para>
Non-polymorphic queries or queries whose polymorphism is restricted can be specified using entity
type expressions (see <xref linkend="jpa_langref_entity_type_expressions"/> )
in the <literal>WHERE</literal> clause to restrict the domain of the query.
For example, the following query returns instances of <classname>Digest</classname>:
<programlisting>
SELECT x FROM Magazine WHERE TYPE(x) = Digest
</programlisting>
</para>
</section>
<section id="jpa_overview_query_params">
<title>
Query Parameters
</title>
<para>
JPQL provides support for parameterized queries. Either named parameters or
positional parameters may be specified in the query string. Parameters allow you
to re-use query templates where only the input parameters vary. A single query
can declare either named parameters or positional parameters, but is not allowed
to declare both named and positional parameters.
</para>
<programlisting>
public Query setParameter (int pos, Object value);
</programlisting>
<para>
Specify positional parameters in your JPQL string using an integer prefixed by a
question mark. You can then populate the <classname>Query</classname> object
with positional parameter values via calls to the <methodname>setParameter
</methodname> method above. The method returns the <classname>Query</classname>
instance for optional method chaining.
</para>
<programlisting>
EntityManager em = ...
Query q = em.createQuery("SELECT x FROM Magazine x WHERE x.title = ?1 and x.price &gt; ?2");
q.setParameter(1, "JDJ").setParameter(2, 5.0);
List&lt;Magazine&gt; results = (List&lt;Magazine&gt;) q.getResultList();
</programlisting>
<para>
This code will substitute <literal>JDJ</literal> for the <literal>?1</literal>
parameter and <literal>5.0</literal> for the <literal>?2</literal> parameter,
then execute the query with those values.
</para>
<programlisting>
public Query setParameter(String name, Object value);
</programlisting>
<para>
Named parameters are denoted by prefixing an arbitrary name with a colon in your
JPQL string. You can then populate the <classname> Query</classname> object with
parameter values using the method above. Like the positional parameter method,
this method returns the <classname>Query</classname> instance for optional
method chaining.
</para>
<programlisting>
EntityManager em = ...
Query q = em.createQuery("SELECT x FROM Magazine x WHERE x.title = :titleParam and x.price &gt; :priceParam");
q.setParameter("titleParam", "JDJ").setParameter("priceParam", 5.0);
List&lt;Magazine&gt; results = (List&lt;Magazine&gt;) q.getResultList();
</programlisting>
<para>
This code substitutes <literal>JDJ</literal> for the <literal> :titleParam
</literal> parameter and <literal>5.0</literal> for the <literal>:priceParam
</literal> parameter, then executes the query with those values.
</para>
<para>
All input parameters must be single-valued, except in IN expressions
(see <xref linkend="jpa_langref_in_expressions"/>), which support the use of collection-valued
input parameters.
</para>
</section>
<section id="jpa_overview_query_hints">
<title>
Query Hints
</title>
<para>
JPQL provides support for hints which are name/value pairs used to control locking and optimization keywords in SQL.
The following example shows how to use the JPA hint API to set the <classname>ReadLockMode</classname>
and <classname>ResultCount</classname> in the OpenJPA fetch plan. This will result in
a database-specific SQL keyword (usually FOR UPDATE) to be emitted into the SQL provided that a
pessimistic LockManager is being used. Additionally, if a DB2 database is being used,
the OPTIMIZE FOR 2 ROWS clause will also be emitted.
</para>
<example id="jpa_query_hint1">
<title>
Query Hints
</title>
<programlisting>
...
Query q = em.createQuery("select m from Magazine m where ... ");
q.setHint("openjpa.hint.OptimizeResultCount", new Integer(2));
q.setHint("openjpa.FetchPlan.ReadLockMode","WRITE");
List r = q.getResultList();
...
</programlisting>
</example>
<para>
Hints which can not be processed by a particular database or are unknown to OpenJPA are ignored.
Hints known to OpenJPA but supplied with an incompatible value will result in an
<classname>IllegalArgumentException</classname> being thrown.
</para>
<section id="jpa_hints_locking">
<title>
Locking Hints
</title>
<para>
To avoid deadlock and optimistic update exceptions among multiple updaters, use a pessimistic LockManager, specified in the persistence unit definition,
and use a hint name of &quot;openjpa.FetchPlan.ReadLockMode&quot; on queries for entities that must be locked for serialization.
The value of <classname>ReadLockMode</classname> can be either &quot;READ&quot; or &quot;WRITE&quot;.
This results in a database-specific locking keyword (usually FOR UPDATE) to be emitted into the SQL.
</para>
<para>
Using a <classname>ReadLockMode</classname> hint with JPA optimistic locking (i.e. specifying LockManager = &quot;version&quot;) will result in the entity version field either being reread at end of transaction in the case of a value of &quot;READ&quot; or the version field updated at end of transaction in the case of &quot;WRITE&quot;. You must define a version field in the entity mapping when using a version LockManager and using ReadLockMode.
</para>
<table>
<title>
Interaction of ReadLockMode hint and LockManager
</title>
<tgroup cols="3" align="left" colsep="1" rowsep="1">
<colspec colname="interaction"/>
<colspec colname="pessimistic"/>
<colspec colname="version"/>
<thead>
<row>
<entry colname="read-lock">
ReadLockMode
</entry>
<entry colname="pessimistic">
LockManager=pessimistic
</entry>
<entry colname="version">
LockManager=version
</entry>
</row>
</thead>
<tbody>
<row>
<entry colname="interaction">
READ
</entry>
<entry colname="pessimistic">
SQL with FOR UPDATE
</entry>
<entry colname="version">SQL without FOR UPDATE;
<para>
reread version field at the end of transaction and check for no change.
</para>
</entry>
</row>
<row>
<entry colname="interaction">
WRITE
</entry>
<entry colname="pessimistic">
SQL with FOR UPDATE
</entry>
<entry colname="version">
SQL without FOR UPDATE;
<para>
force update version field at the end of transaction
</para>
</entry>
</row>
<row>
<entry colname="interaction">
not specified
</entry>
<entry colname="pessimistic">
SQL without FOR UPDATE
</entry>
<entry colname="version">
SQL without FOR UPDATE
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="jpa_hints_locktimeout">
<title>
Lock Timeout Hint
</title>
<para>
To specify a lock timeout hint in milliseconds to those databases that support
it, specify a hint name of &quot;openjpa.LockTimeout&quot; or
&quot;javax.persistence.lock.timeout&quot; with an integer value greater than
zero, or zero for no timeout which is the default behavior.
</para>
</section>
<section id="jpa_hints_querytimeout">
<title>
Query Timeout Hint
</title>
<para>
To specify a query timeout hint in milliseconds to those database drivers that
support it, specify a hint name of &quot;javax.persistence.query.timeout&quot;
with an integer value greater than zero, or zero for no timeout which is the
default behavior.
</para>
</section>
<section id="jpa_hints_resultset">
<title>
Result Set Size Hint
</title>
<para>
To specify a result set size hint to those databases that support it, specify a hint name of &quot;openjpa.hint.OptimizeResultCount&quot; with an integer value greater than zero. This causes the SQL keyword OPTIMIZE FOR to be generated.
</para>
</section>
<section id="jpa_hints_isolation">
<title>
Isolation Level Hint
</title>
<para>
To specify an isolation level, specify a hint name of &quot;openjpa.FetchPlan.Isolation&quot;. The value will be used to specify isolation level using the SQL WITH &lt;isolation&gt; clause for those databases that support it. This hint only works in conjunction with the ReadLockMode hint.
</para>
</section>
<section id="jpa_hints_fetchplan">
<title>
Other Fetchplan Hints
</title>
<para>
Any property of an OpenJPA FetchPlan can be changed using a hint by using a name of the form &quot;openjpa.FetchPlan.&quot;&lt;property name&gt;. Valid property names include:
<classname>MaxFetchDepth</classname>, <classname>FetchBatchSize</classname>, <classname>LockTimeOut</classname>, <classname>EagerFetchMode</classname>, <classname>SubclassFetchMode</classname> and <classname>Isolation</classname>.
</para>
</section>
<section>
<title>
Database-Specific Hints
</title>
<para>
The hint names &quot;openjpa.hint.MySQLSelectHint&quot; and
&quot;openjpa.hint.OracleSelectHint&quot; can be used to specify a string value
of a query hint that will be inserted into SQL for MySQL and Oracle databases.
See <xref linkend="dbsupport_mysql_query_hints"/> and
<xref linkend="dbsupport_oracle_query_hints"/> for examples.
</para>
</section>
<section id="jpa_hints_named">
<title>
Named Query Hints
</title>
<para>
Hints can also be included as part of a NamedQuery definition.
</para>
<example id="jpa_query_hint2">
<title>
Named Query using Hints
</title>
<programlisting>
...
@NamedQuery(name="magsOverPrice",
query="SELECT x FROM Magazine x WHERE x.price > ?1",
hints={
@QueryHint(name="openjpa.hint.OptimizeResultCount", value="2"),
@QueryHint(name="openjpa.FetchPlan.ReadLockMode", value="WRITE")
}
)
...
</programlisting>
</example>
</section>
<section id="multi-hints-handling">
<title>
Handling of Multiple Similar Query Hints
</title>
<para>
When similar hints in different prefix scopes are specified in a query,
the following prefix precedence order is used to select the effective hint:
<itemizedlist>
<listitem>
javax.persistence.*
</listitem>
<listitem>
openjpa.FetchPlan.*
</listitem>
<listitem>
openjpa.jdbc.*
</listitem>
<listitem>
openjpa.*
</listitem>
</itemizedlist>
<example id="multi-hints-example">
<title>
Setting Multiple Similar Query Hints
</title>
<programlisting>
...
Query q = em.createQuery(.....);
q.setHint("openjpa.FetchPlan.LockTimeout", 1000);
q.setHint("javax.persistence.lock.timeout", 2000);
q.setHint("openjpa.LockTimeout", 3000);
// Lock time out of 2000 ms is in effect for query q
...
</programlisting>
</example>
</para>
</section>
</section>
<section id="jpa_overview_query_ordering">
<title>
Ordering
</title>
<para>
JPQL queries may optionally contain an <literal>order by</literal> clause which
specifies one or more fields to order by when returning query results. You may
follow the <literal>order by field</literal> clause with the <literal>asc
</literal> or <literal>desc</literal> keywords, which indicate that ordering
should be ascending or descending, respectively. If the direction is omitted,
ordering is ascending by default.
</para>
<programlisting>
SELECT x FROM Magazine x order by x.title asc, x.price desc
</programlisting>
<para>
The query above returns <classname>Magazine</classname> instances sorted by
their title in ascending order. In cases where the titles of two or more
magazines are the same, those instances will be sorted by price in descending
order.
</para>
</section>
<section id="jpa_overview_query_aggregates">
<title>
Aggregates
</title>
<para>
JPQL queries can select aggregate data as well as objects. JPQL includes the
<literal>min</literal>, <literal>max</literal>, <literal>avg</literal>, and
<literal>count</literal> aggregates. These functions can be used for reporting
and summary queries.
</para>
<para>
The following query will return the average of all the prices of all the
magazines:
</para>
<programlisting>
EntityManager em = ...
Query q = em.createQuery("SELECT AVG(x.price) FROM Magazine x");
Number result = (Number) q.getSingleResult();
</programlisting>
<para>
The following query will return the highest price of all the magazines titled
"JDJ":
</para>
<programlisting>
EntityManager em = ...
Query q = em.createQuery("SELECT MAX(x.price) FROM Magazine x WHERE x.title = 'JDJ'");
Number result = (Number) q.getSingleResult();
</programlisting>
</section>
<section id="jpa_overview_query_named">
<title>
Named Queries
</title>
<para>
Query templates can be statically declared using the <literal> NamedQuery
</literal> and <literal>NamedQueries</literal> annotations. For example:
</para>
<programlisting>
@Entity
@NamedQueries({
@NamedQuery(name="magsOverPrice",
query="SELECT x FROM Magazine x WHERE x.price &gt; ?1"),
@NamedQuery(name="magsByTitle",
query="SELECT x FROM Magazine x WHERE x.title = :titleParam")
})
public class Magazine {
...
}
</programlisting>
<para>
These declarations will define two named queries called <literal>magsOverPrice
</literal> and <literal>magsByTitle</literal>.
</para>
<programlisting>
public Query createNamedQuery(String name);
</programlisting>
<para>
You retrieve named queries with the above <classname>EntityManager</classname>
method. For example:
</para>
<programlisting>
EntityManager em = ...
Query q = em.createNamedQuery("magsOverPrice");
q.setParameter(1, 5.0f);
List&lt;Magazine&gt; results = (List&lt;Magazine&gt;) q.getResultList();
</programlisting>
<programlisting>
EntityManager em = ...
Query q = em.createNamedQuery("magsByTitle");
q.setParameter("titleParam", "JDJ");
List&lt;Magazine&gt; results = (List&lt;Magazine&gt;) q.getResultList();
</programlisting>
</section>
<section id="jpa_overview_query_delete">
<title>
Delete By Query
</title>
<para>
Queries are useful not only for finding objects, but for efficiently deleting
them as well. For example, you might delete all records created before a certain
date. Rather than bring these objects into memory and delete them individually,
JPA allows you to perform a single bulk delete based on JPQL criteria.
</para>
<para>
Delete by query uses the same JPQL syntax as normal queries, with one exception:
begin your query string with the <literal>delete</literal> keyword instead of
the <literal>select</literal> keyword. To then execute the delete, you call the
following <classname>Query</classname> method:
</para>
<programlisting>
public int executeUpdate();
</programlisting>
<para>
This method returns the number of objects deleted. The following example deletes
all subscriptions whose expiration date has passed.
</para>
<example id="jpa_overview_query_deleteex">
<title>
Delete by Query
</title>
<programlisting>
Query q = em.createQuery("DELETE FROM Subscription s WHERE s.subscriptionDate &lt; :today");
q.setParameter("today", new Date());
int deleted = q.executeUpdate();
</programlisting>
</example>
</section>
<section id="jpa_overview_query_update">
<title>
Update By Query
</title>
<para>
Similar to bulk deletes, it is sometimes necessary to perform updates against a
large number of queries in a single operation, without having to bring all the
instances down to the client. Rather than bring these objects into memory and
modifying them individually, JPA allows you to perform a single bulk update
based on JPQL criteria.
</para>
<para>
Update by query uses the same JPQL syntax as normal queries, except that the
query string begins with the <literal>update</literal> keyword instead of
<literal>select</literal>. To execute the update, you call the following
<classname>Query</classname> method:
</para>
<programlisting>
public int executeUpdate();
</programlisting>
<para>
This method returns the number of objects updated. The following example updates
all subscriptions whose expiration date has passed to have the "paid" field set
to true..
</para>
<example id="jpa_overview_query_updateex">
<title>
Update by Query
</title>
<programlisting>
Query q = em.createQuery("UPDATE Subscription s SET s.paid = :paid WHERE s.subscriptionDate &lt; :today");
q.setParameter("today", new Date());
q.setParameter("paid", true);
int updated = q.executeUpdate();
</programlisting>
</example>
</section>
</section>
<section id="jpa_langref">
<title>
JPQL Language Reference
</title>
<para>
The Java Persistence Query Language (JPQL) is used to define searches against
persistent entities independent of the mechanism used to store those entities.
As such, JPQL is "portable", and not constrained to any particular data store.
The Java Persistence query language is an extension of the Enterprise JavaBeans
query language, <literal>EJB QL</literal>, adding operations such as bulk
deletes and updates, join operations, aggregates, projections, and subqueries.
Furthermore, JPQL queries can be declared statically in metadata, or can be
dynamically built in code. This chapter provides the full definition of the
language.
</para>
<note>
<para>
Much of this section is paraphrased or taken directly from Chapter 4 of the
JSR 317 Java Persistence API Specification.
</para>
</note>
<section id="jpa_langref_stmnttypes">
<title>
JPQL Statement Types
</title>
<para>
A JPQL statement may be either a <literal>SELECT</literal> statement, an
<literal>UPDATE</literal> statement, or a <literal>DELETE</literal> statement.
This chapter refers to all such statements as "queries". Where it is important
to distinguish among statement types, the specific statement type is referenced.
In BNF syntax, a query language statement is defined as:
</para>
<itemizedlist>
<listitem>
<para>
QL_statement ::= select_statement | update_statement | delete_statement
</para>
</listitem>
</itemizedlist>
<para>
The complete BNF for JPQL is defined in <xref linkend="jpa_langref_bnf"/>.
Any JPQL statement may be constructed dynamically or may be statically defined
in a metadata annotation or XML descriptor element. All statement types may
have parameters, as discussed in <xref linkend="jpa_langref_input_params"/>.
</para>
<section id="jpa_langref_select">
<title>
JPQL Select Statement
</title>
<para>
A select statement is a string which consists of the following clauses:
</para>
<itemizedlist>
<listitem>
<para>
a <literal>SELECT</literal> clause, which determines the type of the objects
or values to be selected.
</para>
</listitem>
<listitem>
<para>
a <literal>FROM</literal> clause, which provides declarations that designate the
domain to which the expressions specified in the other clauses of the query
apply.
</para>
</listitem>
<listitem>
<para>
an optional <literal>WHERE</literal> clause, which may be used to restrict the
results that are returned by the query.
</para>
</listitem>
<listitem>
<para>
an optional <literal>GROUP BY</literal> clause, which allows query results to be
aggregated in terms of groups.
</para>
</listitem>
<listitem>
<para>
an optional <literal>HAVING</literal> clause, which allows filtering over
aggregated groups.
</para>
</listitem>
<listitem>
<para>
an optional <literal>ORDER BY</literal> clause, which may be used to order the
results that are returned by the query.
</para>
</listitem>
</itemizedlist>
<para>
In BNF syntax, a select statement is defined as:
</para>
<itemizedlist>
<listitem>
<para>
select_statement ::= select_clause from_clause [where_clause] [groupby_clause]
[having_clause] [orderby_clause]
</para>
</listitem>
</itemizedlist>
<para>
A select statement must always have a <literal>SELECT</literal> and a
<literal>FROM</literal> clause. The square brackets [] indicate that the other
clauses are optional.
</para>
</section>
<section id="jpa_langref_bulk">
<title>
JPQL Update and Delete Statements
</title>
<para>
Update and delete statements provide bulk operations over sets of entities. In
BNF syntax, these operations are defined as:
</para>
<itemizedlist>
<listitem>
<para>
update_statement ::= update_clause [where_clause]
</para>
</listitem>
<listitem>
<para>
delete_statement ::= delete_clause [where_clause]
</para>
</listitem>
</itemizedlist>
<para>
The update and delete clauses determine the type of the entities to be updated
or deleted. The <literal>WHERE</literal> clause may be used to restrict the
scope of the update or delete operation. Update and delete statements are
described further in <xref linkend="jpa_langref_bulk_ops"/>.
</para>
</section>
</section>
<section id="jpa_langref_schematypes">
<title>
JPQL Abstract Schema Types and Query Domains
</title>
<para>
The Java Persistence query language is a typed language, and every expression
has a type. The type of an expression is derived from the structure of the
expression, the abstract schema types of the identification variable
declarations, the types to which the persistent fields and relationships
evaluate, and the types of literals.
</para>
<para>
The abstract schema type of an entity or embeddable is
derived from the entity class and the metadata information provided by Java
language annotations or in the XML descriptor.
</para>
<para>
Informally, the abstract schema type of an entity or embeddable can be characterized as
follows:
</para>
<itemizedlist>
<listitem>
<para>
For every persistent field or get
accessor method (for a persistent property) of the entity class, there is a
field ("state-field") whose abstract schema type corresponds to that of the
field or the result type of the accessor method.
</para>
</listitem>
<listitem>
<para>
For every persistent relationship field or get accessor method (for a persistent
relationship property) of the entity class, there is a field
("association-field") whose type is the abstract schema type of the related
entity (or, if the relationship is a one-to-many or many-to-many, a collection
of such).
</para>
</listitem>
</itemizedlist>
<para>
Abstract schema types are specific to the query language data model.
The persistence provider is not required to implement or otherwise materialize
an abstract schema type.
</para>
<para>
The domain of a query consists of the abstract schema
types of all entities and embeddables that are defined in the same persistence unit.
</para>
<para>
The domain
of a query may be restricted by the <literal>navigability</literal> of the relationships of the
entity and associated embeddable classes on which it is based. The association-fields of an entity's
or embeddable's abstract
schema type determine navigability. Using the association fields and their
values, a query can select related entities and use their abstract schema types
in the query.
</para>
<section id="jpa_langref_schemanaming">
<title>
JPQL Entity Naming
</title>
<para>
Entities are designated in query strings by their entity names. The entity name
is defined by the name element of the Entity annotation (or the entity-name XML
descriptor element), and defaults to the unqualified name of the entity class.
Entity names are scoped within the persistence unit and must be unique within
the persistence unit.
</para>
</section>
<section id="jpa_langref_schemaexample">
<title>
JPQL Schema Example
</title>
<para>
This example assumes that the application developer provides several entity
classes, representing magazines, publishers, authors, and articles. The abstract
schema types for these entities are <literal>Magazine</literal>, <literal>
Publisher</literal>, <literal>Author</literal>, and <literal>Article</literal>.
</para>
<para>
Several Entities with Abstract Persistence Schemas Defined in the Same
Persistence Unit. The entity <literal>Publisher</literal> has a one-to-many
relationships with <literal>Magazine</literal>. There is also a one-to-many
relationship between <literal>Magazine</literal> and <literal>Article</literal>
. The entity <literal>Article</literal> is related to <literal>Author</literal>
in a one-to-one relationship.
</para>
<para>
Queries to select magazines can be defined by navigating over the
association-fields and state-fields defined by <literal>Magazine</literal> and
<literal>Author</literal>. A query to
find all magazines that have unpublished articles is as follows:
</para>
<programlisting>
SELECT DISTINCT mag FROM Magazine AS mag JOIN mag.articles AS art WHERE art.published = FALSE
</programlisting>
<para>
This query navigates over the association-field <literal>authors</literal> of the
abstract schema type <literal>Magazine</literal> to find articles, and uses the
state-field <literal>published</literal> of <literal>Article</literal> to select
those magazines that have at least one article that is not published. Although
predefined reserved identifiers, such as <literal>DISTINCT</literal>, <literal>
FROM</literal>, <literal>AS</literal>, <literal>JOIN</literal>, <literal>
WHERE</literal>, and <literal>FALSE</literal> appear in upper case in this
example, predefined reserved identifiers are case insensitive.
</para>
<para>
The <literal>
SELECT</literal> clause of this example designates the return type of this
query to be of type <literal>Magazine</literal>.
</para>
<para>
Because the same persistence unit defines the
abstract persistence schemas of the related entities, the developer can also
specify a query over articles that utilizes the abstract
schema type for products, and hence the state-fields and association-fields of
both the abstract schema types <literal>Magazine</literal> and <literal>Author</literal>.
For example, if the
abstract schema type <literal>Author</literal> has a state-field named <literal>firstName</literal>,
a query over
articles can be specified using this state-field. Such a query might be to
find all magazines that have articles authored by someone with the first name
"John".
</para>
<programlisting>
SELECT DISTINCT mag FROM Magazine mag JOIN mag.articles art JOIN art.author auth WHERE auth.firstName = 'John'
</programlisting>
<para>
Because <literal>Magazine</literal> is related to <literal>Author</literal> by means of the
relationships between <literal>Magazine</literal> and <literal>Article</literal>
and between <literal>Article</literal> and <literal>Author</literal>,
navigation using the association-fields <literal>authors</literal> and
<literal>product</literal> is used to express
the query. This query is specified by using the abstract schema name <literal>Magazine</literal>,
which designates the abstract schema type over which the query ranges. The basis
for the navigation is provided by the association-fields <literal>authors</literal>
and <literal>product</literal> of
the abstract schema types <literal>Magazine</literal> and <literal>Article</literal> respectively.
</para>
</section>
</section>
<section id="jpa_langref_fromclause">
<title>
JPQL FROM Clause and Navigational Declarations
</title>
<para>
The <literal>FROM</literal> clause of a query defines the domain of the query by
declaring identification variables. An identification variable is an identifier
declared in the <literal>FROM</literal> clause of a query. The domain of the
query may be constrained by path expressions (See section <xref linkend="jpa_langref_path"/>.
</para>
<para>
Identification variables designate
instances of a particular entity abstract schema type. The <literal>FROM
</literal> clause can contain multiple identification variable declarations
separated by a comma (,).
</para>
<itemizedlist>
<listitem>
<para>
from_clause ::= FROM identification_variable_declaration {,
{identification_variable_declaration | collection_member_declaration}}*
</para>
</listitem>
<listitem>
<para>
identification_variable_declaration ::= range_variable_declaration { join |
fetch_join }*
</para>
</listitem>
<listitem>
<para>
range_variable_declaration ::= abstract_schema_name [AS] identification_variable
</para>
</listitem>
<listitem>
<para>
join ::= join_spec join_association_path_expression [AS] identification_variable
</para>
</listitem>
<listitem>
<para>
fetch_join ::= join_spec FETCH join_association_path_expression
</para>
</listitem>
<listitem>
<para>
join_association_path_expression ::= join_collection_valued_path_expression |
join_single_valued_association_path_expression
</para>
</listitem>
<listitem>
<para>
join_collection_valued_path_expression::=
identification_variable.{single_valued_embeddable_object_field.}*collection_valued_field
</para>
</listitem>
<listitem>
<para>
join_single_valued_path_expression::=
identification_variable.{single_valued_embeddable_object_field.}*single_valued_object_field </para>
</listitem>
<listitem>
<para>
join_spec ::= [ LEFT [OUTER] | INNER ] JOIN
</para>
</listitem>
<listitem>
<para>
collection_member_declaration ::= IN (collection_valued_path_expression) [AS]
identification_variable
</para>
</listitem>
</itemizedlist>
<para>
The following subsections discuss the constructs used in the <literal>FROM</literal> clause.
</para>
<section id="jpa_langref_from_identifiers">
<title>
JPQL FROM Identifiers
</title>
<para>
An identifier is a character sequence of unlimited length. The character
sequence must begin with a Java identifier start character, and all other
characters must be Java identifier part characters. An identifier start
character is any character for which the method <methodname>
Character.isJavaIdentifierStart</methodname> returns <literal>true</literal>.
This includes the underscore (_) character and the dollar sign ($) character. An
identifier part character is any character for which the method <methodname>
Character.isJavaIdentifierPart</methodname> returns <literal>true</literal>.
The question mark (?) character is reserved for use by the Java Persistence
query language. The following are reserved identifiers:
</para>
<itemizedlist>
<listitem>
<para>
<literal>ABS</literal>
</para>
</listitem>
<listitem>
<para>
<literal>ALL</literal>
</para>
</listitem>
<listitem>
<para>
<literal>AND</literal>
</para>
</listitem>
<listitem>
<para>
<literal>ANY</literal>
</para>
</listitem>
<listitem>
<para>
<literal>AS</literal>
</para>
</listitem>
<listitem>
<para>
<literal>ASC</literal>
</para>
</listitem>
<listitem>
<para>
<literal>AVG</literal>
</para>
</listitem>
<listitem>
<para>
<literal>BETWEEN</literal>
</para>
</listitem>
<listitem>
<para>
<literal>BOTH</literal>
</para>
</listitem>
<listitem>
<para>
<literal>BY</literal>
</para>
</listitem>
<listitem>
<para>
<literal>CASE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>CLASS</literal>
</para>
</listitem>
<listitem>
<para>
<literal>COALESCE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>CONCAT</literal>
</para>
</listitem>
<listitem>
<para>
<literal>COUNT</literal>
</para>
</listitem>
<listitem>
<para>
<literal>CURRENT_DATE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>CURRENT_TIME</literal>
</para>
</listitem>
<listitem>
<para>
<literal>CURRENT_TIMESTAMP</literal>
</para>
</listitem>
<listitem>
<para>
<literal>DELETE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>DESC</literal>
</para>
</listitem>
<listitem>
<para>
<literal>DISTINCT</literal>
</para>
</listitem>
<listitem>
<para>
<literal>ELSE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>EMPTY</literal>
</para>
</listitem>
<listitem>
<para>
<literal>END</literal>
</para>
</listitem>
<listitem>
<para>
<literal>ENTRY</literal>
</para>
</listitem>
<listitem>
<para>
<literal>ESCAPE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>EXISTS</literal>
</para>
</listitem>
<listitem>
<para>
<literal>FALSE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>FETCH</literal>
</para>
</listitem>
<listitem>
<para>
<literal>FROM</literal>
</para>
</listitem>
<listitem>
<para>
<literal>GROUP</literal>
</para>
</listitem>
<listitem>
<para>
<literal>HAVING</literal>
</para>
</listitem>
<listitem>
<para>
<literal>IN</literal>
</para>
</listitem>
<listitem>
<para>
<literal>INDEX</literal>
</para>
</listitem>
<listitem>
<para>
<literal>INNER</literal>
</para>
</listitem>
<listitem>
<para>
<literal>IS</literal>
</para>
</listitem>
<listitem>
<para>
<literal>JOIN</literal>
</para>
</listitem>
<listitem>
<para>
<literal>KEY</literal>
</para>
</listitem>
<listitem>
<para>
<literal>LEADING</literal>
</para>
</listitem>
<listitem>
<para>
<literal>LEFT</literal>
</para>
</listitem>
<listitem>
<para>
<literal>LENGTH</literal>
</para>
</listitem>
<listitem>
<para>
<literal>LIKE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>LOCATE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>LOWER</literal>
</para>
</listitem>
<listitem>
<para>
<literal>MAX</literal>
</para>
</listitem>
<listitem>
<para>
<literal>MEMBER</literal>
</para>
</listitem>
<listitem>
<para>
<literal>MIN</literal>
</para>
</listitem>
<listitem>
<para>
<literal>MOD</literal>
</para>
</listitem>
<listitem>
<para>
<literal>NEW</literal>
</para>
</listitem>
<listitem>
<para>
<literal>NOT</literal>
</para>
</listitem>
<listitem>
<para>
<literal>NULL</literal>
</para>
</listitem>
<listitem>
<para>
<literal>NULLIF</literal>
</para>
</listitem>
<listitem>
<para>
<literal>OBJECT</literal>
</para>
</listitem>
<listitem>
<para>
<literal>OF</literal>
</para>
</listitem>
<listitem>
<para>
<literal>OR</literal>
</para>
</listitem>
<listitem>
<para>
<literal>ORDER</literal>
</para>
</listitem>
<listitem>
<para>
<literal>OUTER</literal>
</para>
</listitem>
<listitem>
<para>
<literal>SELECT</literal>
</para>
</listitem>
<listitem>
<para>
<literal>SET</literal>
</para>
</listitem>
<listitem>
<para>
<literal>SIZE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>SOME</literal>
</para>
</listitem>
<listitem>
<para>
<literal>SQRT</literal>
</para>
</listitem>
<listitem>
<para>
<literal>SIBSTRING</literal>
</para>
</listitem>
<listitem>
<para>
<literal>SUM</literal>
</para>
</listitem>
<listitem>
<para>
<literal>THEN</literal>
</para>
</listitem>
<listitem>
<para>
<literal>TRAILING</literal>
</para>
</listitem>
<listitem>
<para>
<literal>TRIM</literal>
</para>
</listitem>
<listitem>
<para>
<literal>TRUE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>TYPE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>UPDATE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>UPPER</literal>
</para>
</listitem>
<listitem>
<para>
<literal>VALUE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>WHEN</literal>
</para>
</listitem>
<listitem>
<para>
<literal>WHERE</literal>
</para>
</listitem>
<listitem>
<para>
<literal>CHARACTER_LENGTH</literal>
</para>
</listitem>
<listitem>
<para>
<literal>CHAR_LENGTH</literal>
</para>
</listitem>
<listitem>
<para>
<literal>BIT_LENGTH</literal>
</para>
</listitem>
<listitem>
<para>
<literal>POSITION</literal>
</para>
</listitem>
<listitem>
<para>
<literal>UNKNOWN</literal>
</para>
</listitem>
</itemizedlist>
<para>
Reserved identifiers are case insensitive. Reserved identifiers must not be
used as identification variables or result variables.
</para>
<note>
<para>
It is recommended that other SQL reserved
words also not be used as identification variables in queries because they may be
used as reserved identifiers in future releases of the specification.
</para>
</note>
<note>
<para>
BIT_LENGTH, CHAR_LENGTH, CHARACTER_LENGTH, POSITION, and UNKNOWN are not currently used: they are
reserved for future use.
</para>
</note>
</section>
<section id="jpa_langref_from_vars">
<title>
JPQL Identification Variables
</title>
<para>
An identification variable is a valid identifier declared in the <literal>FROM
</literal> clause of a query.
</para>
<para>
All identification variables must be declared in
the <literal>FROM</literal> clause. Identification variables cannot be declared
in other clauses.
</para>
<para>
An identification variable must not be a reserved identifier
or have the same name as any entity in the same persistence unit.
</para>
<para>
Identification variables are case insensitive.
</para>
<para>
An identification variable evaluates to a value
of the type of the expression used in declaring the variable. For example,
consider the previous query: <programlisting>SELECT DISTINCT mag FROM Magazine mag JOIN mag.articles art JOIN art.author auth WHERE auth.firstName = 'John'
</programlisting>
In the <literal>FROM</literal> clause declaration <literal>
mag.articles</literal> <literal>art</literal>, the identification variable
<literal>art</literal> evaluates to any <literal>Article</literal> value
directly reachable from <literal>Magazine</literal>. The association-field
<literal>articles</literal> is a collection of instances of the abstract schema
type <literal>Article</literal> and the identification variable <literal>art
</literal> refers to an element of this collection. The type of <literal>auth
</literal> is the abstract schema type of <literal>Author</literal>.
</para>
<para>
An identification variable can range over an entity,
embeddable, or basic abstract schema type. An
identification variable designates an instance of an entity abstract schema type
or an element of a collection of entity abstract schema type instances.
</para>
<para>
Note that for identification variables referring to an instance of an association or collection represented
as a <literal>java.util.Map</literal>, the identification variable is of the abstract schema type of the map
<literal>value</literal>.
</para>
<para>
An
identification variable always designates a reference to a single value. It is
declared in one of three ways: in a range variable declaration, in a join
clause, or in a collection member declaration. The identification variable
declarations are evaluated from left to right in the <literal>FROM</literal>
clause, and an identification variable declaration can use the result of a
preceding identification variable declaration of the query string.
</para>
<para>
All identification variables used in the <literal>SELECT</literal>,
<literal>WHERE</literal>,
<literal>ORDER BY</literal>,
<literal>GROUP BY</literal>, or
<literal>HAVING</literal>
clause of a <literal>SELECT</literal> or
<literal>DELETE</literal> statement must be declared in the <literal>FROM</literal> clause.
The identification
variables used in the <literal>WHERE</literal> clause of
an <literal>UPDATE</literal> statement must be declared in the <literal>UPDATE</literal> clause.
</para>
<para>
Identification variables are existentially quantified in these clauses. This means that an identification
variable represents a member of a collection or an instance of an entity’s abstract schema type. An identification
variable never designates a collection in its entirety.
</para>
<para>
An identification variable is scoped to the query (or subquery) in which it is defined and is also visible
to any subqueries within that query scope that do not define an identification variable of the same name.
</para>
</section>
<section id="jpa_langref_range">
<title>
JPQL Range Declarations
</title>
<para>
The syntax for declaring an identification variable as a range variable is
similar to that of SQL; optionally, it uses the AS keyword. A range variable designates an
entity abstract schema type.
</para>
<note>
<para>
A range variable must not designate an embeddable class abstract schema type.
</para>
</note>
<itemizedlist>
<listitem>
<para>
range_variable_declaration ::= entity_name [AS]
identification_variable
</para>
</listitem>
</itemizedlist>
<para>
Range variable declarations allow the developer to designate a "root" for
objects which may not be reachable by navigation.
</para>
<para>
In order to select values by
comparing more than one instance of an entity abstract schema type, more than
one identification variable ranging over the abstract schema type is needed in
the <literal>FROM</literal> clause.
</para>
<para>
The following query returns magazines whose price is greater than the price of
magazines published by "Adventure" publishers. This example illustrates the use
of two different identification variables in the <literal>FROM</literal> clause,
both of the abstract schema type Magazine. The <literal>SELECT</literal> clause
of this query determines that it is the magazines with prices greater than those
of "Adventure" publisher's that are returned.
</para>
<programlisting>
SELECT DISTINCT mag1 FROM Magazine mag1, Magazine mag2
WHERE mag1.price &gt; mag2.price AND mag2.publisher.name = 'Adventure'
</programlisting>
</section>
<section id="jpa_langref_path">
<title>
JPQL Path Expressions
</title>
<para>
An identification variable followed by the navigation operator (.) and a
state-field or association-field is a path expression. The type of the path
expression is the type computed as the result of navigation; that is, the type
of the state-field or association-field to which the expression navigates.
</para>
<para>
An identification variable qualified by the <literal>KEY</literal>,
<literal>VALUE</literal>, or <literal>ENTRY</literal>
operator is a path expression. The
<literal>KEY</literal>, <literal>VALUE</literal>,
and <literal>ENTRY</literal> operators may only be applied to identification variables that correspond to
map-valued associations or map-valued element collections. The type of the path expression is the type
computed as the result of the operation; that is, the abstract schema type of the field that is the value of
the <literal>KEY</literal>,
<literal>VALUE</literal>, or <literal>ENTRY</literal>
operator (the map key, map value, or map entry respectively).
</para>
<note>
<para>
Note that use of <literal>VALUE</literal> is optional,
as an identification variable referring to an association of type
<literal>java.util.Map</literal> is of the
abstract schema type of the map value.
</para>
</note>
<para>
The syntax for qualified identification variables is as follows.
</para>
<itemizedlist>
<listitem>
<para>
qualified_identification_variable :: =
KEY(identification_variable) |
VALUE(identification_variable) |
ENTRY(identification_variable)
</para>
</listitem>
</itemizedlist>
<para>
A path expression using the <literal>KEY</literal> or <literal>VALUE</literal>
operator may be further composed. A path expression
using the <literal>ENTRY</literal> operator is terminal.
It cannot be further composed and can only appear in the
<literal>SELECT</literal> list of a query.
</para>
<para>
In the following query, <literal>photos</literal> is a map from photo label to filename.
</para>
<programlisting>
SELECT i.name, VALUE(p)
FROM Item i JOIN i.photos p
WHERE KEY(p) LIKE ‘egret’
</programlisting>
<para>
In the above query the identification variable <literal>p</literal> designates
an abstract schema type corresponding to the
map value. The results of <literal>VALUE(p)</literal> and <literal>KEY(p)</literal>
are the map value and the map key associated with
p, respectively. The following query is equivalent:
</para>
<programlisting>
SELECT i.name, p
FROM Item i JOIN i.photos p
WHERE KEY(p) LIKE ‘egret’
</programlisting>
<para>
Depending on navigability, a path expression that leads to a association-field
or to a field whose type is an embeddable class
may be further composed. Path expressions can be composed from other path
expressions if the original path expression evaluates to a single-valued type
(not a collection) corresponding to a association-field.
</para>
<para>
In the following example, <literal>contactInfo</literal> denotes an embeddable
class consisting of an address and
set of phones. <literal>Phone</literal> is an entity.
</para>
<programlisting>
SELECT p.vendor
FROM Employee e JOIN e.contactInfo.phones p
WHERE e.contactInfo.address.zipcode = '95054'
</programlisting>
<para>
Path expression
navigability is composed using "inner join" semantics. That is, if the value of
a non-terminal association-field in the path expression is null, the path is
considered to have no value, and does not participate in the determination of
the result.
</para>
<para>
The following query is equivalent to the query above:
</para>
<programlisting>
SELECT p.vendor
FROM Employee e JOIN e.contactInfo c JOIN c.phones p
WHERE e.contactInfo.address.zipcode = '95054'
</programlisting>
<para>
The syntax for single-valued path expressions and collection valued
path expressions is as follows:
</para>
<itemizedlist>
<listitem>
<para>
single_valued_path_expression ::=
qualified_identification_variable |
state_field_path_expression |
single_valued_object_path_expression
</para>
</listitem>
<listitem>
<para>
state_field_path_expression ::=
general_identification_variable.{single_valued_object_field.}*state_field
</para>
</listitem>
<listitem>
<para>
single_valued_object_path_expression ::=
general_identification_variable.{single_valued_object_field.}*single_valued_object_field
</para>
</listitem>
<listitem>
<para>
collection_valued_path_expression ::=
general_identification_variable.{single_valued_object_field.}*collection_valued_field
</para>
</listitem>
</itemizedlist>
<para>
A <literal>single_valued_object_field</literal> is designated by the name of an
association-field in a one-to-one or many-to-one relationship
or a field of embeddable class type. The type of a
<literal>single_valued_object_field</literal> is the abstract schema type of the
related entity or embeddable class.
</para>
<para>
A <literal>state_field</literal> is designated by the name of an entity or
embeddable class state field that corresponds to
a basic type.
</para>
<para>
A collection_valued_field is designated by the name
of an association-field in a one-to-many or a many-to-many relationship
or by the name of an element collection field. The
type of a <literal>collection_valued_field</literal> is
a collection of values of the
abstract schema type of the related entity
or element type.
</para>
<para>
An identification variable used in a
<literal>single_valued_object_path_expression</literal> or in a
<literal>collection_valued_path_expression</literal>
may be an unqualified identification variable or an identification
variable to which the KEY or VALUE function has been applied.
</para>
<itemizedlist>
<listitem>
<para>
general_identification_variable ::=
identification_variable |
KEY(identification_variable) |
VALUE(identification_variable)
</para>
</listitem>
</itemizedlist>
<para>
It is syntactically illegal to compose a path expression from a
path expression that evaluates to a collection. For example, if <literal>mag
</literal> designates <literal>Magazine</literal>, the path expression <literal>
mag.articles.author</literal> is illegal since navigation to authors results in
a collection. This case should produce an error when the query string is
verified. To handle such a navigation, an identification variable must be
declared in the <literal>FROM</literal> clause to range over the elements of the
<literal>articles</literal> collection. Another path expression must be used to
navigate over each such element in the <literal>WHERE</literal> clause of the
query, as in the following query which returns all authors that have any
articles in any magazines:
</para>
<programlisting>
SELECT DISTINCT art.author FROM Magazine AS mag, IN(mag.articles) art
</programlisting>
<para>
It is illegal to use a <literal>collection_valued_path_expression</literal> other than
in the <literal>FROM</literal> clause of a query
except in an <literal>empty_collection_comparison_expression</literal>,
in a <literal>collection_member_expression</literal>, or
as an argument to the <literal>SIZE</literal> operator.
See <xref linkend="jpa_langref_empty_comp"/>, <xref linkend="jpa_langref_collection_member"/>,
and <xref linkend="jpa_langref_arithmetic"/>.
</para>
</section>
<section id="jpa_langref_Joins">
<title>
JPQL Joins
</title>
<para>
An inner join may be implicitly specified by the use of a cartesian product in
the <literal>FROM</literal> clause and a join condition in the <literal>WHERE
</literal> clause. In the absence of a join condition, this reduces to the cartesian product.
</para>
<para>
The main use case for this generalized style of join is when a join condition does not involve
a foreign key relationship that is mapped to an entity relationship, for example:
</para>
<programlisting>SELECT c FROM Customer c, Employee e WHERE c.hatsize = e.shoesize</programlisting>
<para>
In general, use of this style of inner join (also referred to as theta-join) is less typical than explicitly
defined joins over relationships.
</para>
<para>
The syntax for explicit join operations is as follows:
</para>
<itemizedlist>
<listitem>
<para>
join ::= join_spec join_association_path_expression [AS] identification_variable
</para>
</listitem>
<listitem>
<para>
fetch_join ::= join_spec FETCH join_association_path_expression
</para>
</listitem>
<listitem>
<para>
join_association_path_expression ::= join_collection_valued_path_expression |
join_single_valued_path_expression
</para>
</listitem>
<listitem>
<para>
join_collection_valued_path_expression::=
identification_variable.{single_valued_embeddable_object_field.}*collection_valued_field
</para>
</listitem>
<listitem>
<para>
join_single_valued_path_expression::=
identification_variable.{single_valued_embeddable_object_field.}*single_valued_object_field
</para>
</listitem>
<listitem>
<para>
join_spec ::= [ LEFT [OUTER] | INNER ] JOIN
</para>
</listitem>
</itemizedlist>
<para>
The inner and outer join operation types described in
<xref linkend="jpa_langref_inner_joins"/> and <xref linkend="jpa_langref_outer_joins"/> are supported.
</para>
<section id="jpa_langref_inner_joins">
<title>
JPQL Inner Joins (Relationship Joins)
</title>
<para>
The syntax for the inner join operation is <itemizedlist>
<listitem>
[ INNER ] JOIN join_association_path_expression [AS] identification_variable
</listitem>
</itemizedlist> For example, the query below joins over the relationship
between publishers and magazines. This type of join typically equates to a join
over a foreign key relationship in the database.
</para>
<programlisting>
SELECT pub FROM Publisher pub JOIN pub.magazines mag WHERE pub.revenue &gt; 1000000
</programlisting>
<para>
The keyword <literal>INNER</literal> may optionally be used:
</para>
<programlisting>
SELECT pub FROM Publisher pub INNER JOIN pub.magazines mag WHERE pub.revenue &gt; 1000000
</programlisting>
<para>
This is equivalent to the following query using the earlier
<literal>IN</literal> construct. It selects those publishers with revenue of
over 1 million for which at least one magazine exists:
</para>
<programlisting>
SELECT OBJECT(pub) FROM Publisher pub, IN(pub.magazines) mag WHERE pub.revenue &gt; 1000000
</programlisting>
<para>
The query below joins over Employee, ContactInfo and Phone. ContactInfo is an
embeddable class that consists of an address and set of phones. Phone is an entity.
</para>
<programlisting>
SELECT p.vendor
FROM Employee e JOIN e.contactInfo c JOIN c.phones p
WHERE c.address.zipcode = '95054'
</programlisting>
</section>
<section id="jpa_langref_outer_joins">
<title>
JPQL Outer Joins
</title>
<para>
<literal>LEFT JOIN</literal> and <literal>LEFT OUTER JOIN</literal> are
synonymous. They enable the retrieval of a set of entities where matching values
in the join condition may be absent. The syntax for a left outer join is:
<itemizedlist>
<listitem>LEFT [OUTER] JOIN join_association_path_expression [AS] identification_variable
</listitem>
</itemizedlist>
</para>
<para>
For example: <programlisting>SELECT pub FROM Publisher pub LEFT JOIN pub.magazines mag WHERE pub.revenue &gt; 1000000
</programlisting> The keyword <literal>OUTER</literal> may optionally be used:
<programlisting>SELECT pub FROM Publisher pub LEFT OUTER JOIN pub.magazines mags WHERE pub.revenue &gt; 1000000
</programlisting> An important use case for <literal>LEFT JOIN</literal> is in
enabling the prefetching of related data items as a side effect of a query. This
is accomplished by specifying the <literal>LEFT JOIN</literal> as a <literal>
FETCH JOIN</literal>.
</para>
</section>
<section id="jpa_langref_fetch_joins">
<title>
JPQL Fetch Joins
</title>
<para>
A <literal>FETCH JOIN</literal> enables the fetching of an association as a side
effect of the execution of a query. A <literal>FETCH JOIN</literal> is specified
over an entity and its related entities. The syntax for a fetch join is
<itemizedlist><listitem><para>fetch_join ::= [ LEFT [OUTER] | INNER ] JOIN
FETCH join_association_path_expression
</para>
</listitem>
</itemizedlist>
</para>
<para>
The association referenced by the right side of the <literal>FETCH JOIN
</literal> clause must be an association that belongs to an entity that is
returned as a result of the query. It is not permitted to specify an
identification variable for the entities referenced by the right side of the
<literal>FETCH JOIN</literal> clause, and hence references to the implicitly
fetched entities cannot appear elsewhere in the query.
</para>
<para>
The following query
returns a set of magazines. As a side effect, the associated articles for those
magazines are also retrieved, even though they are not part of the explicit
query result. The persistent fields or properties of the articles that are
eagerly fetched are fully initialized. The initialization of the relationship
properties of the <literal>articles</literal> that are retrieved is determined
by the metadata for the <literal>Article</literal> entity class.
<programlisting>SELECT mag FROM Magazine mag LEFT JOIN FETCH mag.articles WHERE mag.id = 1
</programlisting>
</para>
<para>
A fetch join has the same join semantics as the corresponding inner or outer
join, except that the related objects specified on the right-hand side of the
join operation are not returned in the query result or otherwise referenced in
the query. Hence, for example, if magazine id 1 has five articles, the above
query returns five references to the magazine 1 entity.
</para>
<para>
The <literal>FETCH JOIN</literal> construct must not be used in the FROM clause of a subquery.
</para>
</section>
</section>
<section id="jpa_langref_collection_dec">
<title>
JPQL Collection Member Declarations
</title>
<para>
An identification variable declared by a <literal>collection_member_declaration</literal> ranges
over values of a collection obtained by navigation using a path expression. Such
a path expression represents a navigation involving the association-fields of an
entity abstract schema type. Because a path expression can be based on another
path expression, the navigation can use the association-fields of related
entities.
</para>
<para>
An identification variable of a collection member declaration is
declared using a special operator, the reserved identifier <literal>IN</literal>
. The argument to the <literal>IN</literal> operator is a collection-valued path
expression. The path expression evaluates to a collection type specified as a
result of navigation to a collection-valued association-field of an entity
or embeddable class
abstract schema type.
</para>
<para>
The syntax for declaring a collection member
identification variable is as follows:
</para>
<para>
<itemizedlist><listitem><para>collection_member_declaration ::= IN
(collection_valued_path_expression) [AS] identification_variable
</para>
</listitem>
</itemizedlist>
</para>
<para>
For example, the query <programlisting>SELECT DISTINCT mag FROM Magazine mag
JOIN mag.articles art
JOIN art.author auth
WHERE auth.lastName = 'Grisham'</programlisting> can equivalently be
expressed as follows, using the <literal>IN</literal> operator: <programlisting>SELECT DISTINCT mag FROM Magazine mag,
IN(mag.articles) art
WHERE art.author.lastName = 'Grisham'</programlisting> In this example,
<literal>articles</literal> is the name of an association-field whose value is a
collection of instances of the abstract schema type <literal>Article</literal>.
The identification variable <literal>art</literal> designates a member of this
collection, a single <literal>Article</literal> abstract schema type instance.
In this example, <literal>mag</literal> is an identification variable of the
abstract schema type <literal>Magazine</literal>.
</para>
</section>
<section id="jpa_langref_from_clause_and_sql">
<title>
JPQL FROM Clause and SQL
</title>
<para>
The Java Persistence query language treats the FROM clause similarly to SQL in that the declared identification
variables affect the results of the query even if they are not used in the WHERE clause. Application
developers should use caution in defining identification variables because the domain of the
query can depend on whether there are any values of the declared type.
</para>
<para>
For example, the <literal>FROM</literal> clause below defines a query over
all orders that have line items and existing
products. If there are no <literal>Product</literal> instances in the database,
the domain of the query is empty and no
order is selected.
</para>
<programlisting>
SELECT o
FROM Order AS o JOIN o.lineItems l JOIN l.product p
</programlisting>
</section>
<section id="jpa_langref_polymorph">
<title>
JPQL Polymorphism
</title>
<para>
Java Persistence queries are automatically polymorphic. The <literal>FROM
</literal> clause of a query designates not only instances of the specific
entity classes to which explicitly refers but of subclasses as well. The
instances returned by a query include instances of the subclasses that satisfy
the query criteria.
</para>
<para>
Non-polymorphic queries or queries whose polymorphism is restricted can be specified using entity
type expressions in the <literal>WHERE</literal> clause to restrict the domain of the query.
See <xref linkend="jpa_langref_entity_type_expressions"/>.
</para>
</section>
</section>
<section id="jpa_langref_where">
<title>
JPQL WHERE Clause
</title>
<para>
The <literal>WHERE</literal> clause of a query consists of a conditional
expression used to select objects or values that satisfy the expression. The
<literal>WHERE</literal> clause restricts the result of a select statement or
the scope of an update or delete operation.
</para>
<para>
A <literal>WHERE</literal> clause is
defined as follows: <itemizedlist><listitem><para>where_clause ::= WHERE
conditional_expression
</para>
</listitem>
</itemizedlist>
</para>
<para>
The <literal>GROUP BY</literal> construct enables the aggregation of values
according to the properties of an entity class. The <literal>HAVING</literal>
construct enables conditions to be specified that further restrict the query
result as restrictions upon the groups.
</para>
<para>
The syntax of the <literal>HAVING
</literal> clause is as follows: <itemizedlist><listitem><para>having_clause
::= HAVING conditional_expression
</para>
</listitem>
</itemizedlist>
</para>
<para>
The <literal>GROUP BY</literal> and <literal>HAVING</literal> constructs are
further discussed in <xref linkend="jpa_langref_group"/>.
</para>
</section>
<section id="jpa_langref_cond">
<title>
JPQL Conditional Expressions
</title>
<para>
The following sections describe the language constructs that can be used in a
conditional expression of the <literal>WHERE</literal> clause or <literal>
HAVING</literal> clause.
</para>
<para>
State-fields that are mapped in serialized form or as
LOBs may not be portably used in conditional expressions. <note><para> The
implementation is not expected to perform such query operations involving such
fields in memory rather than in the database.
</para>
</note>
</para>
<section id="jpa_langref_lit">
<title>
JPQL Literals
</title>
<para>
A string literal is enclosed in single quotes--for example: 'literal'. A string
literal that includes a single quote is represented by two single quotes--for
example: 'literal''s'. String literals in queries, like Java String literals,
use unicode character encoding. The use of Java escape notation is not supported
in query string literals.
</para>
<para>
Exact numeric literals support the use of Java integer
literal syntax as well as SQL exact numeric literal syntax.
</para>
<para>
Approximate literals
support the use of Java floating point literal syntax as well as SQL approximate
numeric literal syntax.
</para>
<para>
Enum literals support the use of Java enum literal
syntax. The enum class name must be specified.
</para>
<para>
Appropriate suffixes can be used
to indicate the specific type of a numeric literal in accordance with the Java
Language Specification. The boolean literals are <literal>TRUE</literal> and
<literal>FALSE</literal>. Although predefined reserved literals appear in upper
case, they are case insensitive.
</para>
<para>
The JDBC escape syntax may be used for the specification of date, time, and timestamp literals. For
example:
</para>
<programlisting>
SELECT o
FROM Customer c JOIN c.orders o
WHERE c.name = 'Smith'
AND o.submissionDate &lt; {d '2008-12-31'}
</programlisting>
<para>
Date, time, and timestamp literals are passed as is to the JDBC driver
in use.
</para>
<para>
Entity type literals are specified by entity names—for example: <literal>Customer</literal>.
</para>
<para>
Although reserved literals appear in upper case, they are case insensitive.
</para>
</section>
<section id="jpa_langref_idvar">
<title>
JPQL Identification Variables
</title>
<para>
All identification variables used in the <literal>WHERE</literal> or <literal>
HAVING</literal> clause of a <literal>SELECT</literal> or <literal>DELETE
</literal> statement must be declared in the <literal>FROM</literal> clause, as
described in <xref linkend="jpa_langref_from_vars"/>. The identification
variables used in the <literal>WHERE</literal> clause of an <literal>UPDATE
</literal> statement must be declared in the <literal>UPDATE</literal> clause.
</para>
<para>
Identification variables are existentially quantified in the <literal>WHERE
</literal> and <literal>HAVING</literal> clause. This means that an
identification variable represents a member of a collection or an instance of an
entity's abstract schema type. An identification variable never designates a
collection in its entirety.
</para>
</section>
<section id="jpa_langref_path_exp">
<title>
JPQL Path Expressions
</title>
<para>
It is illegal to use a <literal>collection_valued_path_expression</literal> within a <literal>
WHERE</literal> or <literal>HAVING</literal> clause as part of a conditional
expression except in an <literal>empty_collection_comparison_expression</literal>, in a
<literal>collection_member_expression</literal>, or as an argument to the <literal>SIZE</literal>
operator.
</para>
</section>
<section id="jpa_langref_input_params">
<title>
JPQL Input Parameters
</title>
<para>
Either positional or named parameters may be used. Positional and named
parameters may not be mixed in a single query.
</para>
<para>
Input parameters can only be used
in the <literal>WHERE</literal> clause or <literal>HAVING</literal> clause of a
query.
</para>
<para>
Note that if an input parameter value is null, comparison operations or
arithmetic operations involving the input parameter will return an unknown
value. See <xref linkend="jpa_langref_null_values"/>.
</para>
<para>
All input parameters must be single-valued, except in IN expressions (see
<xref linkend="jpa_langref_in_expressions"/> ), which support the use of collection-valued
input parameters.
</para>
<section id="jpa_langref_pos_params">
<title>
JPQL Positional Parameters
</title>
<para>
The following rules apply to positional parameters. <itemizedlist><listitem>
<para> Input parameters are designated by the question mark (?) prefix followed
by an integer. For example: ?1.
</para>
</listitem>
<listitem>
<para>
Input parameters are numbered starting from 1.
</para>
</listitem>
<listitem>
<para>
The same parameter can
be used more than once in the query string.
</para>
</listitem>
<listitem>
<para>
The ordering of the use of
parameters within the query string need not conform to the order of the
positional parameters.
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section id="jpa_langref_named_params">
<title>
JPQL Named Parameters
</title>
<para>
A named parameter is an identifier that is prefixed by the ":" symbol. It
follows the rules for identifiers defined in
<xref linkend="jpa_langref_from_identifiers"/>. Named parameters are case
sensitive.
</para>
<para>
Example: <programlisting>SELECT pub FROM Publisher pub WHERE pub.revenue &gt; :rev
</programlisting>
</para>
<para>
The same named parameter can be used more than once in the query string.
</para>
</section>
</section>
<section id="jpa_langref_cond_comp">
<title>
JPQL Conditional Expression Composition
</title>
<para>
Conditional expressions are composed of other conditional expressions,
comparison operations, logical operations, path expressions that evaluate to
boolean values, boolean literals, and boolean input parameters.
</para>
<para>
The scalar expressions described in <xref linkend="jpa_langref_scalar_expressions"/>
can be used in conditional expressions.
</para>
<para>
Standard bracketing ()
for ordering expression evaluation is supported.
</para>
<para>
Aggregate functions can only be used in conditional expressions in a <literal>
HAVING</literal> clause. See <xref linkend="jpa_langref_group"/>.
</para>
<para>
Conditional expressions are
defined as follows:
</para>
<para>
<itemizedlist><listitem><para>conditional_expression ::= conditional_term |
conditional_expression OR conditional_term
</para>
</listitem>
<listitem>
<para>
conditional_term ::= conditional_factor | conditional_term AND
conditional_factor
</para>
</listitem>
<listitem>
<para>
conditional_factor ::= [ NOT ] conditional_primary
</para>
</listitem>
<listitem>
<para>
conditional_primary ::= simple_cond_expression | (conditional_expression)
</para>
</listitem>
<listitem>
<para>
simple_cond_expression ::= comparison_expression | between_expression |
like_expression | in_expression | null_comparison_expression |
empty_collection_comparison_expression | collection_member_expression |
exists_expression
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section id="jpa_langref_operators">
<title>
JPQL Operators and Operator Precedence
</title>
<para>
The operators are listed below in order of decreasing precedence. <itemizedlist>
<listitem><para> Navigation operator (.)
</para>
</listitem>
<listitem>
<para>
Arithmetic operators: +, - unary *, / multiplication and division +, - addition
and subtraction
</para>
</listitem>
<listitem>
<para>
Comparison operators: =, &gt;, &gt;=, &lt;, &lt;=, &lt;&gt; (not equal), [
<literal>NOT</literal> ] <literal>BETWEEN</literal>, [ <literal>NOT</literal> ]
<literal>LIKE</literal>, [ <literal>NOT</literal> ] <literal>IN</literal>,
<literal>IS</literal> [ <literal>NOT</literal> ] <literal>NULL</literal>,
<literal>IS</literal> [ <literal>NOT</literal> ] <literal>EMPTY</literal>, [
<literal>NOT</literal> ] <literal>MEMBER</literal> [ <literal>OF</literal> ]
</para>
</listitem>
<listitem>
<para>
Logical operators: <literal>NOT</literal>, <literal>AND</literal>,
<literal>OR</literal>
</para>
</listitem>
</itemizedlist>
The following sections describe other operators used in specific expressions.
</para>
</section>
<section id="jpa_langref_comparison_expressions">
<title>
JPQL Comparison Expressions
</title>
<para>
The syntax for the use of comparison expressions in a conditional expression is as follows:
</para>
<itemizedlist>
<listitem>
<para>
comparison_expression ::=
string_expression comparison_operator {string_expression | all_or_any_expression} |
boolean_expression { =|&lt;&gt; } {boolean_expression | all_or_any_expression} |
enum_expression { =|&lt;&gt; } {enum_expression | all_or_any_expression} |
datetime_expression comparison_operator
{datetime_expression | all_or_any_expression} |
entity_expression { = | &lt;&gt; } {entity_expression | all_or_any_expression} |
arithmetic_expression comparison_operator
{arithmetic_expression | all_or_any_expression} |
entity_type_expression { = | &lt;&gt; } entity_type_expression}
</para>
</listitem>
<listitem>
<para>
comparison_operator ::= = | &gt; | &gt;= | &lt; | &lt;= | &lt;&gt;
</para>
</listitem>
</itemizedlist>
<para>
Examples:
</para>
<programlisting>
item.cost * 1.08 &lt;= 100.00
</programlisting>
<programlisting>
CONCAT(person.lastName, ‘, ’, person.firstName)) = ‘Jones, Sam’
</programlisting>
<programlisting>
TYPE(e) = ExemptEmployee
</programlisting>
<note>
Comparisons over instances of embeddable class types are not supported.
</note>
</section>
<section id="jpa_langref_between">
<title>
JPQL Between Expressions
</title>
<para>
The syntax for the use of the comparison operator [ <literal>NOT</literal> ]
<literal>BETWEEN</literal> in a conditional expression is as follows:
</para>
<para>
arithmetic_expression [NOT] BETWEEN arithmetic_expression AND
arithmetic_expression | string_expression [NOT] BETWEEN string_expression AND
string_expression | datetime_expression [NOT] BETWEEN datetime_expression AND
datetime_expression
</para>
<para>
The BETWEEN expression <programlisting>x BETWEEN y AND z</programlisting> is
semantically equivalent to: <programlisting>y &lt;= x AND x &lt;= z
</programlisting> The rules for unknown and <literal>NULL</literal> values in
comparison operations apply. See <xref linkend="jpa_langref_null_values"/>
.
</para>
<para>
Examples are: <programlisting>p.age BETWEEN 15 and 19</programlisting> is
equivalent to: <programlisting>p.age &gt;= 15 AND p.age &lt;= 19</programlisting>
</para>
<para>
The following expression:
<programlisting>p.age NOT BETWEEN 15 and 19</programlisting> excludes the range, and is equivalent to:
<programlisting>p.age &lt; 15 OR p.age &gt; 19</programlisting>
</para>
<para>
In the following example, <literal>transactionHistory</literal> is a list of credit card
transactions defined using an order column.
</para>
<programlisting>
SELECT t
FROM CreditCard c JOIN c.transactionHistory t
WHERE c.holder.name = ‘John Doe’ AND INDEX(t) BETWEEN 0 AND 9
</programlisting>
</section>
<section id="jpa_langref_in_expressions">
<title>
JPQL In Expressions
</title>
<para>
The syntax for the use of the comparison operator [ <literal>NOT</literal> ]
<literal>IN</literal> in a conditional expression is as follows:
</para>
<para>
<itemizedlist><listitem><para>in_expression ::= state_field_path_expression
[NOT] IN {( in_item {, in_item}* ) | (subquery) | collection_valued_input_parameter }
</para>
</listitem>
<listitem>
<para>
in_item ::= literal | single_valued_input_parameter
</para>
</listitem>
</itemizedlist>
</para>
<para>
The <literal>state_field_path_expression</literal> must have a string, numeric,
date, time, timestamp, or enum value.
</para>
<para>
The literal and/or input_parameter values must be <literal>like</literal>
the same abstract schema type
of the <literal>state_field_path_expression</literal> in type. (See
<xref linkend="jpa_langref_equality"/> ).
</para>
<para>
The results of the subquery must be <literal>like</literal> the same abstract schema type of the
<literal>state_field_path_expression</literal> in type. Subqueries are discussed in
<xref linkend="jpa_langref_subqueries"/>.
</para>
<para>
Examples:
</para>
<programlisting>o.country IN ('UK', 'US', 'France')
</programlisting> is true for UK and false for Peru, and is equivalent to the
expression: <programlisting>(o.country = 'UK') OR (o.country = 'US') OR (o.country = ' France')
</programlisting> In the following expression: <programlisting>o.country NOT IN ('UK', 'US', 'France')
</programlisting> is false for UK and true for Peru, and is equivalent to the
expression: <programlisting>NOT ((o.country = 'UK') OR (o.country = 'US') OR (o.country = 'France'))
</programlisting>
<para>
There must be at least one element in the comma separated list
that defines the set of values for the <literal>IN</literal> expression.
</para>
<para>
If the
value of a <literal>state_field_path_expression</literal> or <literal>in_item</literal>
in an <literal>IN</literal> or <literal>
NOT IN</literal> expression is <literal>NULL</literal> or unknown, the value of
the expression is unknown.
</para>
<para>
Note that use of a collection-valued input parameter will mean that a static query cannot
be precompiled.
</para>
</section>
<section id="jpa_langref_like">
<title>
JPQL Like Expressions
</title>
<para>
The syntax for the use of the comparison operator [ <literal>NOT</literal> ]
<literal>LIKE</literal> in a conditional expression is as follows:
</para>
<para>
like_expression ::=
string_expression [NOT] LIKE <literal>pattern_value</literal> [ESCAPE <literal>escape_character</literal>]
</para>
<para>
The <literal>string_expression</literal> must have a string value.
The <literal>pattern_value</literal> is a string
literal or a string-valued input parameter in which an underscore (_) stands for
any single character, a percent (%) character stands for any sequence of
characters (including the empty sequence), and all other characters stand for
themselves. The optional escape_character is a single-character string literal
or a character-valued input parameter (i.e., char or Character) and is used to
escape the special meaning of the underscore and percent characters in
pattern_value. </para>
<para>
Examples:
</para>
<para>
<itemizedlist><listitem><para><programlisting>address.phone LIKE '12%3'
</programlisting> is true for '123' '12993' and false for '1234'
</para>
</listitem>
<listitem>
<para>
<programlisting>asentence.word LIKE 'l_se'</programlisting> is true for 'lose'
and false for 'loose'
</para>
</listitem>
<listitem>
<para>
<programlisting>aword.underscored LIKE '\_%' ESCAPE '\'</programlisting> is true
for '_foo' and false for 'bar'
</para>
</listitem>
<listitem>
<para>
<programlisting>address.phone NOT LIKE '12%3'</programlisting> is false for
'123' and '12993' and true for '1234'.
</para>
</listitem>
</itemizedlist>
</para>
<para>
If the value of the <literal>string_expression</literal> or
<literal>pattern_value</literal> is <literal>NULL</literal> or unknown, the value of the <literal>
LIKE</literal> expression is unknown. If the <literal>escape_character</literal> is specified and
is <literal>NULL</literal>, the value of the <literal>LIKE</literal> expression
is unknown.
</para>
</section>
<section id="jpa_langref_null">
<title>
JPQL Null Comparison Expressions
</title>
<para>
The syntax for the use of the comparison operator <literal>IS NULL</literal> in
a conditional expression is as follows:
</para>
<para>
null_comparison_expression ::= {single_valued_path_expression | input_parameter } IS [NOT] NULL
</para>
<para>
A null comparison expression tests whether or not the single-valued path
expression or input parameter is a <literal>NULL</literal> value.
</para>
<para>
Null comparisons over instances of embeddable class types are not supported.
</para>
</section>
<section id="jpa_langref_empty_comp">
<title>
JPQL Empty Collection Comparison Expressions
</title>
<para>
The syntax for the use of the comparison operator <literal>IS EMPTY</literal> in
an <literal>empty_collection_comparison_expression</literal> is as follows:
</para>
<para>
empty_collection_comparison_expression ::=
collection_valued_path_expression IS [NOT] EMPTY
</para>
<para>
This expression tests whether or not the collection designated by the
collection-valued path expression is empty (i.e. has no elements).
</para>
<para>
For example, the following query will return all magazines that don't have any
articles at all: <programlisting>SELECT mag FROM Magazine mag WHERE mag.articles IS EMPTY
</programlisting>
</para>
<para>
If the value of the collection-valued path expression in an
empty collection comparison expression is unknown, the value of the empty
comparison expression is unknown.
</para>
</section>
<section id="jpa_langref_collection_member">
<title>
JPQL Collection Member Expressions
</title>
<para>
The syntax for the use of the comparison operator <literal>MEMBER OF</literal>
in an <literal>collection_member_expression</literal> is as follows:
<itemizedlist>
<listitem>
<para>
collection_member_expression ::= entity_or_value_expression [NOT] MEMBER [OF]
collection_valued_path_expression
</para>
</listitem>
<listitem>
<para>
entity_or_value_expression ::= single_valued_object_path_expression |
state_field_path_expression |
simple_entity_or_value_expression
</para>
</listitem>
<listitem>
<para>
simple_entity_or_value_expression ::=
identification_variable |
input_parameter |
literal
</para>
</listitem>
</itemizedlist>
</para>
<para>
This expression tests whether the designated value is a member of the collection
specified by the collection-valued path expression.
</para>
<para>
</para>
Expressions that evaluate to embeddable types are not supported in collection member expressions.
<para>
If the collection valued
path expression designates an empty collection, the value of the <literal>
MEMBER OF</literal> expression is <literal>FALSE</literal> and the value of the
<literal>NOT MEMBER OF</literal> expression is <literal>TRUE</literal>.
Otherwise, if the value of the <literal>collection_valued_path_expression</literal> or
<literal>entity_or_value_expression</literal> in the collection member
expression is <literal>NULL</literal> or unknown, the value of the collection
member expression is unknown.
</para>
<para>
The use of the reserved word OF is optional in this expression.
</para>
<para>
Example:
</para>
<programlisting>
SELECT p
FROM Person p
WHERE 'Joe' MEMBER OF p.nicknames
</programlisting>
</section>
<section id="jpa_langref_exists">
<title>
JPQL Exists Expressions
</title>
<para>
An <literal>EXISTS</literal> expression is a predicate that is true only if the
result of the subquery consists of one or more values and that is false
otherwise. The syntax of an exists expression is <itemizedlist><listitem><para>
exists_expression ::= [NOT] EXISTS (subquery)
</para>
</listitem>
</itemizedlist>
</para>
<para>
Example: <programlisting>SELECT DISTINCT auth FROM Author auth
WHERE EXISTS
(SELECT spouseAuthor FROM Author spouseAuthor WHERE spouseAuthor = auth.spouse)
</programlisting> The result of this query consists of all authors whose spouse
is also an author.
</para>
</section>
<section id="jpa_langref_all_any">
<title>
JPQL All or Any Expressions
</title>
<para>
An <literal>ALL</literal> conditional expression is a predicate
over a subquery that is true if the comparison operation is
true for all values in the result of the subquery or the result of the subquery is empty.
An <literal>ALL</literal> conditional
expression is false if the result of the comparison is false for at least one
value of the result of the subquery,
and is unknown if neither true nor false.
</para>
<para>
An <literal>ANY</literal>
conditional expression is a predicate over a subquery that is true if the comparison operation
is true for some value in the result of the subquery. An <literal>ANY</literal>
conditional expression is false if the result of the subquery is empty or if the
comparison operation is false for every value in the result of the subquery, and
is unknown if neither true nor false. The keyword <literal>SOME</literal> is
synonymous with <literal>ANY</literal>.
</para>
<para>
The comparison operators used with
<literal>ALL</literal> or <literal>ANY</literal> conditional expressions are =,
&lt;, &lt;=, &gt;, &gt;=, &lt;&gt;. The result of the subquery must be like that
of the other argument to the comparison operator in type. See
<xref linkend="jpa_langref_equality"/>. The syntax of an <literal>ALL
</literal> or <literal>ANY</literal> expression is specified as follows:
<itemizedlist><listitem><para>all_or_any_expression ::= { ALL | ANY | SOME}
(subquery)
</para>
</listitem>
</itemizedlist>
</para>
<para>
The following example select the authors who make the highest salary for their
magazine: <programlisting>SELECT auth FROM Author auth
WHERE auth.salary &gt;= ALL(SELECT a.salary FROM Author a WHERE a.magazine = auth.magazine)
</programlisting>
</para>
</section>
<section id="jpa_langref_subqueries">
<title>
JPQL Subqueries
</title>
<para>
Subqueries may be used in the <literal>WHERE</literal> or <literal>HAVING
</literal> clause. The syntax for subqueries is as follows:
</para>
<itemizedlist>
<listitem>
<para>
subquery ::= simple_select_clause subquery_from_clause
[where_clause] [groupby_clause] [having_clause]
</para>
</listitem>
<listitem>
<para>
simple_select_clause ::= SELECT [DISTINCT]
simple_select_expression
</para>
</listitem>
<listitem>
<para>
subquery_from_clause ::= FROM subselect_identification_variable_declaration {,
subselect_identification_variable_declaration |
collection_member_declaration }*
</para>
</listitem>
<listitem>
<para>
subselect_identification_variable_declaration ::=
identification_variable_declaration | derived_path_expression [AS]
identification_variable {join}* | derived_collection_member_declaration
</para>
</listitem>
<listitem>
<para>
simple_select_expression ::= single_valued_path_expression |
scalar_expression |
aggregate_expression | identification_variable
</para>
</listitem>
<listitem>
<para>
derived_path_expression ::=
superquery_identification_variable.{single_valued_object_field.}*collection_valued_field |
superquery_identification_variable.{single_valued_object_field.}*single_valued_object_field
</para>
</listitem>
<listitem>
<para>
derived_collection_member_declaration ::=
IN superquery_identification_variable.{single_valued_object_field.}*collection_valued_field
</para>
</listitem>
</itemizedlist>
<para>
Subqueries are restricted to the <literal>WHERE</literal> and <literal>HAVING
</literal> clauses in this release. Support for subqueries in the <literal>FROM
</literal> clause will be considered in a later release of the specification.
</para>
<para>
Examples: <programlisting>SELECT DISTINCT auth FROM Author auth
WHERE EXISTS (SELECT spouseAuth FROM Author spouseAuth WHERE spouseAuth = auth.spouse)
</programlisting><programlisting>SELECT mag FROM Magazine mag
WHERE (SELECT COUNT(art) FROM mag.articles art) &gt; 10</programlisting>
Note that some contexts in which a subquery can be used require that the
subquery be a scalar subquery (i.e., produce a single result). This is
illustrated in the following example involving a numeric comparison operation.
<programlisting>SELECT goodPublisher FROM Publisher goodPublisher
WHERE goodPublisher.revenue &lt; (SELECT AVG(p.revenue) FROM Publisher p)
</programlisting>
<programlisting>
SELECT goodCustomer
FROM Customer goodCustomer
WHERE goodCustomer.balanceOwed &lt; (
SELECT AVG(c.balanceOwed)/2.0 FROM Customer c)
</programlisting>
</para>
</section>
</section>
<section id="jpa_langref_scalar_expressions">
<title>
JPQL Scalar Expressions
</title>
<para>
Numeric, string, datetime, case, and entity type expressions result in scalar values.
</para>
<para>
Scalar expressions may be used in the <literal>SELECT</literal> clause of a query as well as in the
<literal>WHERE</literal> and <literal>HAVING</literal> clauses.
</para>
<para>
scalar_expression::=
arithmetic_expression |
string_primary |
enum_primary |
datetime_primary |
boolean_primary |
case_expression |
entity_type_expression
</para>
<section id="jpa_langref_math_expressions">
<title>
Arithmetic Expressions
</title>
<para>
The arithmetic operators are:
<itemizedlist>
<listitem>+, - unary</listitem>
<listitem>*, / multiplication and division</listitem>
<listitem>+, - addition and subtraction</listitem>
</itemizedlist>
<para>
Arithmetic operations use numeric promotion.
</para>
<para>
Arithmetic functions are described in <xref linkend="jpa_langref_arithmetic"/>.
</para>
</para>
</section>
<section id="jpa_langref_functional_expressions">
<title>
String, Arithmetic, and Datetime Functional Expressions
</title>
<para>
JPQL includes the built-in functions described in subsections
<xref linkend="jpa_langref_string_fun"/>,
<xref linkend="jpa_langref_arithmetic"/>,
<xref linkend="jpa_langref_datetime"/>,
which may be used in the <literal>SELECT</literal>,
<literal>WHERE</literal>
or <literal>HAVING</literal> clause of a query.
<para>
</para>
If the
value of any argument to a functional expression is null or unknown, the value
of the functional expression is unknown.
</para>
<section id="jpa_langref_string_fun">
<title>
JPQL String Functions
</title>
<para>
<itemizedlist><listitem><para>functions_returning_strings ::=
CONCAT(string_primary, string_primary) | SUBSTRING(string_primary,
simple_arithmetic_expression[, simple_arithmetic_expression]) |
TRIM([[trim_specification] [trim_character] FROM] string_primary) |
LOWER(string_primary) | UPPER(string_primary)
</para>
</listitem>
<listitem>
<para>
trim_specification ::= LEADING | TRAILING | BOTH
</para>
</listitem>
<listitem>
<para>
functions_returning_numerics ::= LENGTH(string_primary) |
LOCATE(string_primary, string_primary[, simple_arithmetic_expression])
</para>
</listitem>
</itemizedlist>
</para>
<para>
The <literal>CONCAT</literal> function returns a string that is a concatenation
of its arguments.
</para>
<para>
The second and third arguments of the <literal>SUBSTRING
</literal> function denote the starting position and length of the substring to
be returned. These arguments are integers.
The third argument is optional. If it is not specified,
the substring from the start position to the end of the string is returned.
The first position of a string is
denoted by 1. The <literal>SUBSTRING</literal> function returns a string.
</para>
<para>
The
<literal>TRIM</literal> function trims the specified character from a string. If
the character to be trimmed is not specified, it is assumed to be space (or
blank). The optional trim_character is a single-character string literal or a
character-valued input parameter (i.e., char or Character). If a trim
specification is not provided, <literal>BOTH</literal> is assumed. The <literal>
TRIM</literal> function returns the trimmed string.
</para>
<para>
The <literal>LOWER</literal>
and <literal>UPPER</literal> functions convert a string to lower and upper case,
respectively. They return a string.
</para>
<para>
The <literal>LOCATE</literal> function
returns the position of a given string within a string, starting the search at a
specified position. It returns the first position at which the string was found
as an integer. The first argument is the string to be located; the second
argument is the string to be searched; the optional third argument is an integer
that represents the string position at which the search is started (by default,
the beginning of the string to be searched). The first position in a string is
denoted by 1. If the string is not found, 0 is returned.
</para>
<para>
The <literal>LENGTH
</literal> function returns the length of the string in characters as an
integer.
</para>
</section>
<section id="jpa_langref_arithmetic">
<title>
JPQL Arithmetic Functions
</title>
<para>
<itemizedlist><listitem><para>functions_returning_numerics ::=
ABS(simple_arithmetic_expression) |
SQRT(simple_arithmetic_expression) |
MOD(simple_arithmetic_expression, simple_arithmetic_expression) |
SIZE(collection_valued_path_expression) |
INDEX(identification_variable)
</para>
</listitem>
</itemizedlist>
</para>
<para>
The <literal>ABS</literal> function takes a numeric argument and returns a
number (integer, float, or double) of the same type as the argument to the
function.
</para>
<para>
The <literal>SQRT</literal> function takes a numeric argument and
returns a double.
</para>
<para>
Note that not all databases support the use of a trim character other than the
space character; use of this argument may result in queries that are not
portable. Note that not all databases support the use of the third argument to
<literal>LOCATE</literal>; use of this argument may result in queries that are
not portable.
</para>
<para>
The <literal>MOD</literal> function takes two integer arguments and returns an
integer.
</para>
<para>
The <literal>SIZE</literal> function returns an integer value, the
number of elements of the collection. If the collection is empty, the <literal>
SIZE</literal> function evaluates to zero. Numeric arguments to these functions
may correspond to the numeric Java object types as well as the primitive numeric
types.
</para>
<para>
The INDEX function returns an integer value corresponding to the position of its argument in an
ordered list. The INDEX function can only be applied to identification variables denoting types for
which an order column has been specified.
</para>
</section>
<section id="jpa_langref_datetime">
<title>
JPQL Datetime Functions
</title>
<para>
functions_returning_datetime:= CURRENT_DATE | CURRENT_TIME | CURRENT_TIMESTAMP
</para>
<para>
The datetime functions return the value of current date, time, and timestamp on
the database server.
</para>
</section>
</section>
<section id="jpa_langref_case_expressions">
<title>
Case Expressions
</title>
<para>
The following forms of case expressions are supported: general case expressions, simple case expressions,
coalesce expressions, and nullif expressions.
<itemizedlist>
<listitem>
case_expression::=
general_case_expression |
simple_case_expression |
coalesce_expression |
nullif_expression
</listitem>
<listitem>
general_case_expression::=
<literal>CASE</literal> when_clause {when_clause}* <literal>ELSE</literal> scalar_expression <literal>END</literal>
</listitem>
<listitem>
when_clause::= <literal>WHEN</literal> conditional_expression <literal>THEN</literal> scalar_expression
</listitem>
simple_case_expression::=
<literal>CASE</literal> case_operand simple_when_clause {simple_when_clause}*
<literal>ELSE</literal> scalar_expression
<literal>END</literal>
<listitem>
case_operand::= state_field_path_expression | type_discriminator
</listitem>
<listitem>
simple_when_clause::= <literal>WHEN</literal> scalar_expression <literal>THEN</literal> scalar_expression
</listitem>
<listitem>
coalesce_expression::= <literal>COALESCE</literal>(scalar_expression {, scalar_expression}+)
</listitem>
<listitem>
nullif_expression::= <literal>NULLIF</literal>(scalar_expression, scalar_expression)
</listitem>
</itemizedlist>
</para>
<para>
Examples:
</para>
<programlisting>
UPDATE Employee e
SET e.salary =
CASE WHEN e.rating = 1 THEN e.salary * 1.1
WHEN e.rating = 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
</programlisting>
<programlisting>
UPDATE Employee e
SET e.salary =
CASE e.rating WHEN 1 THEN e.salary * 1.1
WHEN 2 THEN e.salary * 1.05
ELSE e.salary * 1.01
END
</programlisting>
<programlisting>
SELECT e.name,
CASE TYPE(e) WHEN Exempt THEN 'Exempt'
WHEN Contractor THEN 'Contractor'
WHEN Intern THEN 'Intern'
ELSE 'NonExempt'
END
FROM Employee e
WHERE e.dept.name = 'Engineering'
</programlisting>
<programlisting>
SELECT e.name,
f.name,
CONCAT(CASE WHEN f.annualMiles &gt; 50000 THEN 'Platinum '
WHEN f.annualMiles &gt; 25000 THEN 'Gold '
ELSE ''
END,
'Frequent Flyer')
FROM Employee e JOIN e.frequentFlierPlan f
</programlisting>
</section>
<section id="jpa_langref_entity_type_expressions">
<title>
Entity Type Expressions
</title>
<para>
An entity type expression can be used to restrict query polymorphism.
The <literal>TYPE</literal> operator returns the
exact type of the argument.
</para>
<para>
The syntax of an entity type expression is as follows:
</para>
<itemizedlist>
<listitem>
entity_type_expression ::=
type_discriminator |
entity_type_literal |
input_parameter
</listitem>
<listitem>
type_discriminator ::=
TYPE(identification_variable |
single_valued_object_path_expression |
input_parameter )
</listitem>
</itemizedlist>
<para>
An <literal>entity_type_literal</literal> is designated by the entity name.
</para>
<para>
The Java class of the entity is used as an input parameter to specify the entity type.
</para>
<para>
Examples:
</para>
<programlisting>
SELECT e
FROM Employee e
WHERE TYPE(e) IN (Exempt, Contractor)
</programlisting>
<programlisting>
SELECT e
FROM Employee e
WHERE TYPE(e) IN (:empType1, :empType2)
</programlisting>
<programlisting>
SELECT e
FROM Employee e
WHERE TYPE(e) IN :empTypes
</programlisting>
<programlisting>
SELECT TYPE(e)
FROM Employee e
WHERE TYPE(e) &lt;&gt; Exempt
</programlisting>
</section>
</section>
<section id="jpa_langref_group">
<title>
JPQL GROUP BY, HAVING
</title>
<para>
The <literal>GROUP BY</literal> construct enables the aggregation of values
according to a set of properties. The <literal>HAVING</literal> construct
enables conditions to be specified that further restrict the query result. Such
conditions are restrictions upon the groups.
</para>
<para>
The syntax of the <literal>GROUP
BY</literal> and <literal>HAVING</literal> clauses is as follows:
</para>
<para>
<itemizedlist><listitem><para>groupby_clause ::= GROUP BY groupby_item {,
groupby_item}*
</para>
</listitem>
<listitem>
<para>
groupby_item ::= single_valued_path_expression | identification_variable
</para>
</listitem>
<listitem>
<para>
having_clause ::= HAVING conditional_expression
</para>
</listitem>
</itemizedlist>
</para>
<para>
If a query contains both a <literal>WHERE</literal> clause and a <literal>GROUP
BY</literal> clause, the effect is that of first applying the where clause, and
then forming the groups and filtering them according to the <literal>HAVING
</literal> clause. The <literal>HAVING</literal> clause causes those groups to
be retained that satisfy the condition of the <literal>HAVING</literal> clause.
</para>
<para>
The requirements for the <literal>SELECT</literal> clause when <literal>GROUP
BY</literal> is used follow those of SQL: namely, any item that appears in the
<literal>SELECT</literal> clause (other than as an argument to an aggregate
function) must also appear in the <literal>GROUP BY</literal> clause. In forming
the groups, null values are treated as the same for grouping purposes.
</para>
<para>
Grouping
by an entity is permitted. In this case, the entity must contain no serialized
state fields or LOB-valued state fields that are eagerly fetched.
</para>
<para>
Grouping by embeddables is not supported.
</para>
<para>
The <literal>HAVING</literal> clause
must specify search conditions over the grouping items or aggregate functions
that apply to grouping items.
</para>
<para>
If there is no <literal>GROUP BY</literal> clause and the <literal>HAVING
</literal> clause is used, the result is treated as a single group, and the
select list can only consist of aggregate functions.
The use of <literal>HAVING</literal> in the absence of
<literal>GROUP BY</literal> is not required to be supported by a JPA implementation.
Portable applications should not rely on <literal>HAVING</literal> without the use of
<literal>GROUP BY</literal>.
</para>
<note>
<para>
OpenJPA supports the use of <literal>HAVING</literal> in the absence of
<literal>GROUP BY</literal> if the underlying database supports it.
</para>
</note>
<para>
Examples:
</para>
<programlisting>
SELECT c.status, AVG(c.filledOrderCount), COUNT(c)
FROM Customer c
GROUP BY c.status
HAVING c.status IN (1, 2)
</programlisting>
<programlisting>
SELECT c.country, COUNT(c)
FROM Customer c
GROUP BY c.country
HAVING COUNT(c) &gt; 30
</programlisting>
</section>
<section id="jpa_langref_select_clause">
<title>
JPQL SELECT Clause
</title>
<para>
The <literal>SELECT</literal> clause denotes the query result. More than one
value may be returned from the <literal>SELECT</literal> clause of a query.
</para>
<para>
The <literal>SELECT</literal> clause can contain one or more of the following
elements: a single range variable or identification variable that ranges over an
entity abstract schema type, a single-valued path expression,
a scalar expression,
an aggregate expression, a constructor expression.
</para>
<para>
The <literal>SELECT</literal>
clause has the following syntax:
</para>
<para>
<itemizedlist><listitem><para>select_clause ::= SELECT [DISTINCT]
select_item {, select_item}*
</para>
</listitem>
<listitem>
<para>
select_item ::= select_expression [ [AS] result_variable]
</para>
</listitem>
<listitem>
<para>
select_expression ::= single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable | OBJECT(identification_variable) |
constructor_expression
</para>
</listitem>
<listitem>
<para>
constructor_expression ::= NEW constructor_name ( constructor_item {,
constructor_item}*)
</para>
</listitem>
<listitem>
<para>
constructor_item ::= single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable
</para>
</listitem>
<listitem>
<para>
aggregate_expression ::= { AVG | MAX | MIN | SUM } ([DISTINCT]
state_field_path_expression) | COUNT ([DISTINCT] identification_variable |
state_field_path_expression | single_valued_object_path_expression)
</para>
</listitem>
</itemizedlist>
</para>
<para>
For example: <programlisting>SELECT pub.id, pub.revenue
FROM Publisher pub JOIN pub.magazines mag WHERE mag.price &gt; 5.00
</programlisting>
</para>
<para>
In the following example, videoInventory is a Map from the entity Movie to the number of copies
in stock:
</para>
<programlisting>
SELECT v.location.street, KEY(i).title, VALUE(i)
FROM VideoStore v JOIN v.videoInventory i
WHERE v.location.zipcode = '94301' AND VALUE(i) &gt; 0
</programlisting>
<para>
Note that the <literal>SELECT</literal> clause must be specified to return only
single-valued expressions. The query below is therefore not valid:
<programlisting>SELECT mag.authors FROM Magazine AS mag</programlisting>
</para>
<para>
The <literal>DISTINCT</literal> keyword is used to specify that duplicate values
must be eliminated from the query result.
</para>
<para>
If <literal>DISTINCT</literal> is not
specified, duplicate values are not eliminated.
</para>
<para>
The result of DISTINCT over embeddable objects or map entry results is undefined.
</para>
<para>
Standalone identification
variables in the <literal>SELECT</literal> clause may optionally be qualified by
the <literal>OBJECT</literal> operator. The <literal>SELECT</literal> clause
must not use the OBJECT operator to qualify path expressions.
</para>
<para>
A <literal>result_variable</literal> may be used to name a <literal>select_item</literal> in the query result.
For example,
<programlisting>
SELECT c, COUNT(l) AS itemCount
FROM Customer c JOIN c.Orders o JOIN o.lineItems l
WHERE c.address.state = ‘CA’
ORDER BY itemCount
</programlisting>
</para>
<section id="jpa_langref_resulttype">
<title>
JPQL Result Type of the SELECT Clause
</title>
<para>
The type of the query result specified by the <literal>SELECT</literal> clause
of a query is an entity abstract schema type, a state-field type,
the result of of a scalar expression, the result of
an aggregate function, the result of a construction operation, or some sequence
of these.
</para>
<para>
The result type of the <literal>SELECT</literal> clause is defined by
the result types of the select_expressions contained in it. When multiple
select expressions are used in the <literal>SELECT</literal> clause, the result
of the query is of type Object[], and the elements in this result correspond in
order to the order of their specification in the <literal>SELECT</literal>
clause and in type to the result types of each of the select expressions.
</para>
<para>
The type of the result of a <literal>select_expression</literal> is as follows:
<itemizedlist>
<listitem>
<para>
The result type of an <literal>identification_variable</literal>
is the type of the entity object or embeddable
object to which the identification variable corresponds. The type of an
<literal>identification_variable</literal>
that refers to an entity abstract schema type is the type of the entity to which that identification
variable corresponds or a subtype as determined by the object/relational mapping.
</para>
</listitem>
<listitem>
<para>
The result type of a <literal>single_valued_path_expression</literal> that is a
<literal>state_field_path_expression</literal>
results in an object of the same type as the
corresponding state field of the entity or embeddable class.
If the state field of the entity is a
primitive type, the result type is the corresponding object type.
</para>
</listitem>
<listitem>
<para>
The result type of a <literal>single_valued_path_expression</literal> that is a
<literal>single_valued_object_path_expression</literal>
is the type of the entity object or embeddable
object to which the path expression corresponds.
A <literal>single_valued_object_path_expression</literal>
that results in an entity object will result in an entity of the type of
the relationship field or the
subtype of the relationship field of the entity object as determined by
the object/relational mapping.
</para>
</listitem>
<listitem>
<para>
The result type of a
<literal>single_valued_path_expression</literal>
that is an identification_variable to
which the <literal>KEY</literal> or <literal>VALUE</literal> function
has been applied is determined by the type of the map key
or value respectively, as defined by the above rules
</para>
</listitem>
<listitem>
<para>
The result type of a
<literal>single_valued_path_expression</literal> that is an
<literal>identification_variable</literal> to
which the <literal>ENTRY</literal> function has been applied is
<literal>java.util.Map.Entry</literal>, where the key
and value types of the map entry are determined by the above rules as applied to the map key
and map value respectively.
</para>
</listitem>
<listitem>
<para>
The result type of a
<literal>scalar_expression</literal> is the type of the scalar value to which the expression
evaluates. The result type of a numeric <literal>scalar_expression</literal> is defined in
<xref linkend="jpa_langref_scalar_expressions"/>
</para>
</listitem>
<listitem>
<para>
The result type of an
<literal>entity_type_expression</literal> scalar expression is the Java class to which the
resulting abstract schema type corresponds.
</para>
</listitem>
<listitem>
<para>
The result type of aggregate_expression is defined in
<xref linkend="jpa_langref_aggregates"/>.
</para>
</listitem>
<listitem>
<para>
The result type of a
<literal>constructor_expression</literal> is the type of the class for which
the constructor is defined. The types of the arguments to the constructor are
defined by the above rules.
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section id="jpa_langref_constructor">
<title>
JPQL Constructor Expressions
</title>
<para>
A constructor may be used in the
<literal>SELECT</literal> list to return one or more Java instances. The
specified class is not required to be an entity or to be mapped to the database.
The constructor name must be fully qualified.
</para>
<para>
If an entity class name is specified in the <literal>SELECT NEW</literal>
clause, the resulting entity instances are in the new state.
</para>
<para>
If a <literal>single_valued_path_expression</literal> or
<literal>identification_variable</literal> that is an argument to the constructor
references an entity, the resulting entity instance referenced by that
<literal>single_valued_path_expression</literal> or
<literal>identification_variable</literal>
will be in the managed state.
</para>
<para>
If <literal>PublisherInfo</literal> is an entity class, the following 2 queries return
instances of <literal>PublisherInfo</literal> that will be in the new state.
In the second example, <literal>mag</literal> is an <literal>identification_variable</literal>
passed as an argument to the constructor <literal>PublisherInfo(Magazine mag)</literal>;
the entity instances of <literal>Magazine</literal> created during query evaluation
will be in the managed state.
Example:
</para>
<programlisting>SELECT NEW com.company.PublisherInfo(pub.id, pub.revenue, mag.price)
FROM Publisher pub JOIN pub.magazines mag WHERE mag.price &gt; 5.00
</programlisting>
<programlisting>SELECT NEW com.company.PublisherInfo(mag)
FROM Publisher pub JOIN pub.magazines mag WHERE mag.price &gt; 5.00
</programlisting>
</section>
<section id="jpa_langref_null_select">
<title>
JPQL Null Values in the Query Result
</title>
<para>
If the result of a query corresponds to a association-field or state-field whose
value is null, that null value is returned in the result of the query method.
The <literal>IS NOT NULL</literal> construct can be used to eliminate such null
values from the result set of the query.
</para>
<para>
Note, however, that state-field types
defined in terms of Java numeric primitive types cannot produce <literal>NULL
</literal> values in the query result. A query that returns such a state-field
type as a result type must not return a null value.
</para>
</section>
<section id="jpa_langref_embeddables">
<title>
JPQL Embeddables in the Query Result
</title>
<para>
If the result of a query corresponds to an identification variable or state field whose value is an
embeddable, the embeddable instance returned by the query will not be in the managed state (i.e., it will
not be part of the state of any managed entity).
</para>
<para>
In the following example, the <literal>Address</literal> instances returned by the query will reference Phone
instances. While the <literal>Phone</literal> instances will be managed,
the <literal>Address</literal>> instances referenced by the
<literal>addr</literal> result variable will not be.
Modifications to these embeddable instances are not allowed.
</para>
<programlisting>
@Entity
public class Employee {
@Id int id;
Address address;
...
}
@Embeddable
public class Address {
String street;
...
@OneToOne Phone phone; // fetch=EAGER
}
@Entity
public class Phone {
@Id int id;
...
@OneToOne(mappedBy="address.phone") Employee emp; // fetch=EAGER
}
SELECT e.address AS addr
FROM Employee e
</programlisting>
</section>
<section id="jpa_langref_aggregates">
<title>
JPQL Aggregate Functions
</title>
<para>
The result of a query may be the result
of an aggregate function applied to a path expression.
</para>
<para>
The following aggregate
functions can be used in the <literal>SELECT</literal> clause of a query:
<literal>AVG</literal>, <literal>COUNT</literal>, <literal>MAX</literal>,
<literal>MIN</literal>, <literal>SUM</literal>.
</para>
<para>
For all aggregate functions
except <literal>COUNT</literal>, the path expression that is the argument to
the aggregate function must terminate in a state-field. The path expression
argument to <literal>COUNT</literal> may terminate in either a state-field or a
association-field, or the argument to <literal>COUNT</literal> may be an
identification variable.
</para>
<para>
Arguments to the functions <literal>SUM</literal> and
<literal>AVG</literal> must be numeric. Arguments to the functions <literal>MAX
</literal> and <literal>MIN</literal> must correspond to orderable state-field
types (i.e., numeric types, string types, character types, or date types).
</para>
<para>
The Java type that is contained in the result of a query using an aggregate function
is as follows: <itemizedlist><listitem><para><literal>COUNT</literal> returns
Long.
</para>
</listitem>
<listitem>
<para>
<literal>MAX</literal>, <literal>MIN</literal> return the type of the
state-field to which they are applied.
</para>
</listitem>
<listitem>
<para>
<literal>AVG</literal> returns Double.
</para>
</listitem>
<listitem>
<para>
<literal>SUM</literal> returns Long when applied to state-fields of integral
types (other than BigInteger); Double when applied to state-fields of floating
point types; BigInteger when applied to state-fields of type BigInteger; and
BigDecimal when applied to state-fields of type BigDecimal.
</para>
</listitem>
</itemizedlist>
</para>
<para>
If <literal>SUM
</literal>, <literal>AVG</literal>, <literal>MAX</literal>, or <literal>MIN
</literal> is used, and there are no values to which the aggregate function can
be applied, the result of the aggregate function is <literal>NULL</literal>.
</para>
<para>
If <literal>COUNT</literal> is used, and there are no values to which <literal>
COUNT</literal> can be applied, the result of the aggregate function is 0.
</para>
<para>
The argument to an aggregate function may be preceded by the keyword <literal>
DISTINCT</literal> to specify that duplicate values are to be eliminated before
the aggregate function is applied.
It is legal to specify <literal>DISTINCT</literal> with <literal>MAX</literal>
or <literal>MIN</literal>, but it does not affect the result.
</para>
<para>
Null values are eliminated before the
aggregate function is applied, regardless of whether the keyword <literal>
DISTINCT</literal> is specified.
</para>
<para>
The use of <literal>DISTINCT</literal> with <literal>COUNT</literal> is not supported for arguments of
embeddable types or map entry types.
</para>
<section id="jpa_langref_agg_examples">
<title>
JPQL Aggregate Examples
</title>
<para>
The following query returns the average price of all magazines:
<programlisting>SELECT AVG(mag.price) FROM Magazine mag</programlisting> The
following query returns the sum of all the prices from all the
magazines published by 'Larry': <programlisting>SELECT SUM(mag.price) FROM Publisher pub JOIN pub.magazines mag WHERE pub.firstName = 'Larry'
</programlisting> The following query returns the total number of magazines:
<programlisting>SELECT COUNT(mag) FROM Magazine mag</programlisting>
</para>
</section>
<section id ="jpa_langref_numeric_expressions_in_select">
<title>
JPQL Numeric Expressions in the SELECT Clause
</title>
<para>
The type of a numeric expression in the query result is determined as follows:
</para>
<para>
An operand that corresponds to a persistent state-field is of the same type as that persistent state-field.
</para>
<para>
An operand that corresponds to one of arithmetic functions described in
<xref linkend="jpa_langref_arithmetic"/> is of the type defined by
<xref linkend="jpa_langref_arithmetic"/>.
</para>
<para>
An operand that corresponds to one of an aggregate functions described in
<xref linkend="jpa_langref_aggregates"/> is of the type defined by
<xref linkend="jpa_langref_aggregates"/>.
</para>
<para>
The result of a case expression, coalesce expression, nullif expression, or arithmetic expression (+, -, *,
/) is determined by applying the following rule to its operands.
</para>
<itemizedlist>
<listitem>
<para>
If there is an operand of type Double or double, the result of the operation is of type Double;
</para>
</listitem>
<listitem>
<para>
otherwise, if there is an operand of type Float or float, the result of the operation is of type
Float;
</para>
</listitem>
<listitem>
<para>
otherwise, if there is an operand of type BigDecimal, the result of the operation is of type Big-
Decimal;
</para>
</listitem>
<listitem>
<para>
otherwise, if there is an operand of type BigInteger, the result of the operation is of type BigInteger;
</para>
</listitem>
<listitem>
<para>
otherwise, if there is an operand of type Long or long, the result of the operation is of type
Long;
</para>
</listitem>
<listitem>
<para>
otherwise, if there is an operand of integral type, the result of the operation is of type Integer.
</para>
</listitem>
</itemizedlist>
</section>
</section>
</section>
<section id="jpa_langref_orderby">
<title>
JPQL ORDER BY Clause
</title>
<para>
The <literal>ORDER BY</literal> clause allows the objects or values that are
returned by the query to be ordered. The syntax of the <literal>ORDER BY
</literal> clause is
</para>
<para>
<itemizedlist><listitem><para>orderby_clause ::= ORDER BY orderby_item {,
orderby_item}*
</para>
</listitem>
<listitem>
<para>
orderby_item ::= { state_field_path_expression | result_variable } [ASC | DESC]
</para>
</listitem>
</itemizedlist>
</para>
<para>
An orderby_item must be one of the following:
</para>
<itemizedlist>
<listitem>
<para>
A <literal>state_field_path_expression</literal> that evaluates to an orderable state field of an entity or
embeddable class abstract schema type designated in the SELECT clause by one of the following:
</para>
<itemizedlist>
<listitem>
<para>a <literal>general_identification_variable</literal></para>
</listitem>
<listitem>
<para>a <literal>single_valued_object_path_expression</literal></para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
A <literal>state_field_path_expression</literal> that evaluates to the same state field of the same entity or
embeddable abstract schema type as a <literal>state_field_path_expression</literal>
in the <literal>SELECT</literal> clause.
</para>
</listitem>
<listitem>
<para>
A <literal>result_variable</literal> that refers to an orderable item in the
<literal>SELECT</literal> clause for which the same
<literal>result_variable</literal> has been specified.
This may be the result of an <literal>aggregate_expression</literal>, a
<literal>scalar_expression</literal>,
or a <literal>state_field_path_expression</literal> in the <literal>SELECT</literal> clause.
</para>
</listitem>
</itemizedlist>
<para>
For example, the five queries below are legal.
</para>
<programlisting>
SELECT pub FROM Publisher pub ORDER BY pub.revenue, pub.name
</programlisting>
<programlisting>
SELECT o
FROM Customer c JOIN c.orders o JOIN c.address a
WHERE a.state = ‘CA’
ORDER BY o.quantity DESC, o.totalcost
</programlisting>
<programlisting>
SELECT o.quantity, a.zipcode
FROM Customer c JOIN c.orders o JOIN c.address a
WHERE a.state = ‘CA’
ORDER BY o.quantity, a.zipcode
</programlisting>
<programlisting>
SELECT o.quantity, o.cost*1.08 AS taxedCost, a.zipcode
FROM Customer c JOIN c.orders o JOIN c.address a
WHERE a.state = ‘CA’ AND a.county = ‘Santa Clara’
ORDER BY o.quantity, taxedCost, a.zipcode
</programlisting>
<programlisting>
SELECT AVG(o.quantity) as q, a.zipcode
FROM Customer c JOIN c.orders o JOIN c.address a
WHERE a.state = ‘CA’
GROUP BY a.zipcode
ORDER BY q DESC
</programlisting>
<para>
The following two queries are not legal because the <literal>orderby_item</literal>
is not reflected in the <literal>SELECT</literal>
clause of the query.
</para>
<programlisting>
SELECT p.product_name
FROM Order o JOIN o.lineItems l JOIN l.product p JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
ORDER BY p.price
</programlisting>
<programlisting>
SELECT p.product_name
FROM Order o, IN(o.lineItems) l JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
ORDER BY o.quantity
</programlisting>
<para>
If more than one <literal>orderby_item</literal> is specified, the left-to-right
sequence of the <literal>orderby_item</literal> elements determines the precedence, whereby the
leftmost <literal>orderby_item</literal> has highest precedence.
</para>
<para>
The keyword <literal>ASC</literal>
specifies that ascending ordering be used; the keyword <literal>DESC</literal>
specifies that descending ordering be used. Ascending ordering is the default.
</para>
<para>
SQL rules for the ordering of null values apply: that is, all null values must
appear before all non-null values in the ordering or all null values must appear
after all non-null values in the ordering, but it is not specified which.
</para>
<para>
The
ordering of the query result is preserved in the result of the query method if
the <literal>ORDER BY</literal> clause is used.
</para>
</section>
<section id="jpa_langref_bulk_ops">
<title>
JPQL Bulk Update and Delete
</title>
<para>
Bulk update and delete operations apply to entities of a single
entity class (together with its subclasses, if any). Only one entity abstract
schema type may be specified in the <literal>FROM</literal> or <literal>UPDATE
</literal> clause. The syntax of these operations is as follows:
</para>
<para>
<itemizedlist><listitem><para>update_statement ::= update_clause [where_clause]
</para>
</listitem>
<listitem>
<para>
update_clause ::= UPDATE entity_name [[AS] identification_variable] SET
update_item {, update_item}*
</para>
</listitem>
<listitem>
<para>
update_item ::= [identification_variable.]{state_field |
single_valued_object_field} = new_value
</para>
</listitem>
<listitem>
<para>
new_value ::= scalar_expression |
simple_entity_expression | NULL
</para>
</listitem>
<listitem>
<para>
delete_statement ::= delete_clause [where_clause]
</para>
</listitem>
<listitem>
<para>
delete_clause ::= DELETE FROM entity_name [[AS]
identification_variable]
</para>
</listitem>
</itemizedlist>
</para>
<para>
The syntax of the <literal>WHERE</literal> clause is described in
<xref linkend="jpa_langref_where"/>.
</para>
<para>
A delete operation only applies to
entities of the specified class and its subclasses. It does not cascade to
related entities.
</para>
<para>
The <literal>new_value</literal> specified for an update operation must be
compatible in type with the state-field to which it is assigned.
</para>
<para>
Bulk update
maps directly to a database update operation, bypassing optimistic locking
checks. Portable applications must manually update the value of the version
column, if desired, and/or manually validate the value of the version column.
</para>
<para>
The persistence context is not synchronized with the result of the bulk update
or delete.
</para>
<para>
Caution should be used when executing bulk update or delete
operations because they may result in inconsistencies between the database and
the entities in the active persistence context. In general, bulk update and
delete operations should only be performed within a transaction in a new persistence context or at
the beginning of a transaction (before entities have been accessed whose state
might be affected by such operations).
</para>
<para>
Examples: <programlisting>DELETE FROM Publisher pub WHERE pub.revenue &gt; 1000000.0
</programlisting><programlisting>DELETE FROM Publisher pub WHERE pub.revenue = 0 AND pub.magazines IS EMPTY
</programlisting><programlisting>UPDATE Publisher pub SET pub.status = 'outstanding'
WHERE pub.revenue &lt; 1000000 AND 20 &gt; (SELECT COUNT(mag) FROM pub.magazines mag)
</programlisting>
</para>
</section>
<section id="jpa_langref_null_values">
<title>
JPQL Null Values
</title>
<para>
When the target of a reference does not exist in the database, its value is
regarded as <literal>NULL</literal>. SQL 92 <literal>NULL</literal> semantics
defines the evaluation of conditional expressions containing <literal>NULL
</literal> values. The following is a brief description of these semantics:
</para>
<para>
<itemizedlist><listitem><para> Comparison or arithmetic operations with a
<literal>NULL</literal> value always yield an unknown value.
</para>
</listitem>
<listitem>
<para>
Two <literal>NULL</literal> values are not considered to be equal, the
comparison yields an unknown value.
</para>
</listitem>
<listitem>
<para>
Comparison or arithmetic operations with an unknown value always yield an
unknown value.
</para>
</listitem>
<listitem>
<para>
The <literal>IS NULL</literal> and <literal>IS NOT NULL</literal> operators
convert a <literal>NULL</literal> state-field or single-valued association-field
value into the respective <literal>TRUE</literal> or <literal>FALSE</literal>
value.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Note: The JPQL defines the empty string, "", as a string with 0 length, which is
not equal to a <literal>NULL</literal> value. However, <literal>NULL</literal>
values and empty strings may not always be distinguished when queries are mapped
to some databases. Application developers should therefore not rely on the
semantics of query comparisons involving the empty string and <literal>NULL
</literal> value.
</para>
</section>
<section id="jpa_langref_equality">
<title>
JPQL Equality and Comparison Semantics
</title>
<para>
Only the values of <literal>like</literal> types are permitted to be compared. A type is <literal>like</literal>
another type if they correspond to the same Java language type, or if one is a
primitive Java language type and the other is the wrappered Java class type
equivalent (e.g., <literal>int</literal> and <literal>Integer</literal> are like types in this sense). There is one
exception to this rule: it is valid to compare numeric values for which the
rules of numeric promotion apply. Conditional expressions attempting to compare
non-like type values are disallowed except for this numeric case.
</para>
<para>
Note that the
arithmetic operators and comparison operators are permitted to be applied to
state-fields and input parameters of the wrappered Java class equivalents to the
primitive numeric Java types.
</para>
<para>
Two entities of the same abstract schema type are
equal if and only if they have the same primary key value.
</para>
<para>
Equality/inequality comparisons over enums are supported.
</para>
<para>
Comparisons over instances of embeddable class or map entry types are not supported.
</para>
</section>
<section id="jpa_langref_bnf">
<title>
JPQL BNF
</title>
<para>
The following is the BNF for the Java Persistence query language, from section
4.14 of the JSR 317 specification.
</para>
<itemizedlist>
<listitem>
<para>
QL_statement ::= select_statement | update_statement | delete_statement
</para>
</listitem>
<listitem>
<para>
select_statement ::= select_clause from_clause [where_clause] [groupby_clause]
[having_clause] [orderby_clause]
</para>
</listitem>
<listitem>
<para>
update_statement ::= update_clause [where_clause]
</para>
</listitem>
<listitem>
<para>
delete_statement ::= delete_clause [where_clause]
</para>
</listitem>
<listitem>
<para>
from_clause ::= <literal>FROM</literal> identification_variable_declaration {,
{identification_variable_declaration | collection_member_declaration}}*
</para>
</listitem>
<listitem>
<para>
identification_variable_declaration ::= range_variable_declaration { join |
fetch_join }*
</para>
</listitem>
<listitem>
<para>
range_variable_declaration ::= entity_name [ <literal>AS</literal> ]
identification_variable
</para>
</listitem>
<listitem>
<para>
join ::= join_spec join_association_path_expression [ <literal>AS</literal> ]
identification_variable
</para>
</listitem>
<listitem>
<para>
fetch_join ::= join_spec <literal>FETCH</literal>
join_association_path_expression
</para>
</listitem>
<listitem>
<para>
join_spec ::= [ <literal>LEFT</literal> [ <literal>OUTER</literal> ]| <literal>
INNER</literal> ] <literal>JOIN</literal>
</para>
</listitem>
<listitem>
<para>
join_association_path_expression ::= join_collection_valued_path_expression |
join_single_valued_path_expression
</para>
</listitem>
<listitem>
<para>
join_collection_valued_path_expression ::=
identification_variable.{single_valued_embeddable_object_field.}*collection_valued_field
</para>
</listitem>
<listitem>
<para>
join_single_valued_path_expression ::=
identification_variable.{single_valued_embeddable_object_field.}*single_valued_object_field
</para>
</listitem>
<listitem>
<para>
collection_member_declaration ::= <literal>IN</literal>
(join_collection_valued_path_expression) [ <literal>AS</literal> ]
identification_variable
</para>
</listitem>
<listitem>
<para>
qualified_identification_variable ::=
KEY(identification_variable) |
VALUE(identification_variable) |
ENTRY(identification_variable)
</para>
</listitem>
<listitem>
<para>
single_valued_path_expression ::=
qualified_identification_variable |
state_field_path_expression |
single_valued_object_path_expression
</para>
</listitem>
<listitem>
<para>
general_identification_variable ::=
identification_variable |
KEY(identification_variable) |
VALUE(identification_variable)
</para>
</listitem>
<listitem>
<para>
state_field_path_expression ::=
general_identification_variable.{single_valued_object_field.}*state_field
</para>
</listitem>
<listitem>
<para>
single_valued_object_path_expression ::=
general_identification_variable.{single_valued_object_field.}*
single_valued_object_field
</para>
</listitem>
<listitem>
<para>
collection_valued_path_expression ::=
general_identification_variable.{single_valued_object_field.}*collection_valued_field
</para>
</listitem>
<listitem>
<para>
update_clause ::= <literal>UPDATE</literal> entity_name [[ <literal>AS
</literal> ] identification_variable] <literal>SET</literal> update_item {,
update_item}*
</para>
</listitem>
<listitem>
<para>
update_item ::= [identification_variable.]{state_field |
single_valued_object_field}= new_value
</para>
</listitem>
<listitem>
<para>
new_value ::= scalar_expression |
simple_entity_expression | <literal>NULL
</literal>
</para>
</listitem>
<listitem>
<para>
delete_clause ::= <literal>DELETE</literal><literal>FROM</literal>
entity_name [[ <literal>AS</literal> ] identification_variable]
</para>
</listitem>
<listitem>
<para>
select_clause ::= <literal>SELECT</literal> [ <literal>DISTINCT</literal> ]
select_item {, select_item}*
</para>
</listitem>
<para>
select_item ::= select_expression [[AS] result_variable]
</para>
<listitem>
</listitem>
<listitem>
<para>
select_expression ::= single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable | <literal>OBJECT</literal> (identification_variable)|
constructor_expression
</para>
</listitem>
<listitem>
<para>
constructor_expression ::= <literal>NEW</literal> constructor_name(
constructor_item {, constructor_item}*)
</para>
</listitem>
<listitem>
<para>
constructor_item ::= single_valued_path_expression |
scalar_expression |
aggregate_expression |
identification_variable
</para>
</listitem>
<listitem>
<para>
aggregate_expression ::= { <literal>AVG</literal> | <literal>MAX</literal> |
<literal>MIN</literal> | <literal>SUM</literal> }([ <literal>DISTINCT</literal>
] state_field_path_expression) | <literal>COUNT</literal> ([ <literal>DISTINCT
</literal> ] identification_variable | state_field_path_expression |
single_valued_object_path_expression)
</para>
</listitem>
<listitem>
<para>
where_clause ::= <literal>WHERE</literal> conditional_expression
</para>
</listitem>
<listitem>
<para>
groupby_clause ::= <literal>GROUP</literal><literal>BY</literal> groupby_item {,
groupby_item}*
</para>
</listitem>
<listitem>
<para>
groupby_item ::= single_valued_path_expression | identification_variable
</para>
</listitem>
<listitem>
<para>
having_clause ::= <literal>HAVING</literal> conditional_expression
</para>
</listitem>
<listitem>
<para>
orderby_clause ::= <literal>ORDER</literal><literal>BY</literal> orderby_item {,
orderby_item}*
</para>
</listitem>
<listitem>
<para>
orderby_item ::= state_field_path_expression | result_variable [ <literal>ASC</literal> |
<literal>DESC</literal> ]
</para>
</listitem>
<listitem>
<para>
subquery ::= simple_select_clause subquery_from_clause [where_clause]
[groupby_clause] [having_clause]
</para>
</listitem>
<listitem>
<para>
subquery_from_clause ::= <literal>FROM</literal>
subselect_identification_variable_declaration {,
subselect_identification_variable_declaration |
collection_member_declaration}*
</para>
</listitem>
<listitem>
<para>
subselect_identification_variable_declaration ::=
identification_variable_declaration | derived_path_expression [ <literal>AS
</literal> ] identification_variable | derived_collection_member_declaration
</para>
</listitem>
<listitem>
<para>
derived_path_expression ::=
superquery_identification_variable.{single_valued_object_field.}*collection_valued_field |
superquery_identification_variable.{single_valued_object_field.}*single_valued_object_field
</para>
</listitem>
<listitem>
<para>
derived_collection_member_declaration ::=
IN superquery_identification_variable.{single_valued_object_field.}*collection_valued_field
</para>
</listitem>
<listitem>
<para>
simple_select_clause ::= <literal>SELECT</literal> [ <literal>DISTINCT</literal>
] simple_select_expression
</para>
</listitem>
<listitem>
<para>
simple_select_expression ::= single_valued_path_expression |
scalar_expression | aggregate_expression | identification_variable
</para>
</listitem>
<listitem>
<para>
scalar_expression ::=
simple_arithmetic_expression |
string_primary |
enum_primary |
datetime_primary |
boolean_primary |
case_expression |
entity_type_expression
</para>
</listitem>
<listitem>
<para>
conditional_expression ::= conditional_term | conditional_expression <literal>
OR</literal> conditional_term
</para>
</listitem>
<listitem>
<para>
conditional_term ::= conditional_factor | conditional_term <literal>AND
</literal> conditional_factor
</para>
</listitem>
<listitem>
<para>
conditional_factor ::= [ <literal>NOT</literal> ] conditional_primary
</para>
</listitem>
<listitem>
<para>
conditional_primary ::= simple_cond_expression |(conditional_expression)
</para>
</listitem>
<listitem>
<para>
simple_cond_expression ::= comparison_expression | between_expression |
like_expression | in_expression | null_comparison_expression |
empty_collection_comparison_expression | collection_member_expression |
exists_expression
</para>
</listitem>
<listitem>
<para>
between_expression ::= arithmetic_expression [ <literal>NOT</literal> ]
<literal>BETWEEN</literal> arithmetic_expression <literal>AND</literal>
arithmetic_expression | string_expression [ <literal>NOT</literal> ] <literal>
BETWEEN</literal> string_expression <literal>AND</literal> string_expression |
datetime_expression [ <literal>NOT</literal> ] <literal>BETWEEN</literal>
datetime_expression <literal>AND</literal> datetime_expression
</para>
</listitem>
<listitem>
<para>
in_expression ::= {state_field_path_expression | type_discriminator} [ <literal>NOT</literal> ]
<literal>IN</literal> {( in_item {, in_item}*) | (subquery) | collection_valued_input_parameter }
</para>
</listitem>
<listitem>
<para>
in_item ::= literal | single_valued_input_parameter
</para>
</listitem>
<listitem>
<para>
like_expression ::= string_expression [ <literal>NOT</literal> ] <literal>LIKE
</literal> pattern_value [ <literal>ESCAPE</literal> escape_character]
</para>
</listitem>
<listitem>
<para>
null_comparison_expression ::= {single_valued_path_expression | input_parameter}
<literal>IS</literal> [ <literal>NOT</literal> ] <literal>NULL</literal>
</para>
</listitem>
<listitem>
<para>
empty_collection_comparison_expression ::= collection_valued_path_expression
<literal>IS</literal> [ <literal>NOT</literal> ] <literal>EMPTY</literal>
</para>
</listitem>
<listitem>
<para>
collection_member_expression ::= entity_expression [ <literal>NOT</literal> ]
<literal>MEMBER</literal> [ <literal>OF</literal> ]
collection_valued_path_expression
</para>
</listitem>
<listitem>
<para>
entity_or_value_expression ::=
single_valued_object_path_expression |
state_field_path_expression |
simple_entity_or_value_expression
</para>
</listitem>
<listitem>
<para>
simple_entity_or_value_expression ::=
identification_variable |
input_parameter |
literal
</para>
</listitem>
<listitem>
<para>
exists_expression ::= [ <literal>NOT</literal> ] <literal>EXISTS</literal>
(subquery)
</para>
</listitem>
<listitem>
<para>
all_or_any_expression ::= { <literal>ALL</literal> | <literal>ANY</literal> |
<literal>SOME</literal> }(subquery)
</para>
</listitem>
<listitem>
<para>
comparison_expression ::=
string_expressioncomparison_operator{string_expression|all_or_any_expression}|
boolean_expression {=|&lt;&gt;} {boolean_expression | all_or_any_expression} |
enum_expression {=|&lt;&gt;} {enum_expression | all_or_any_expression} |
datetime_expression comparison_operator {datetime_expression |
all_or_any_expression} | entity_expression {= |&lt;&gt; } {entity_expression |
all_or_any_expression} | arithmetic_expression comparison_operator
{arithmetic_expression | all_or_any_expression} |
entity_type_expression { =|&lt;&gt;>} entity_type_expression}
</para>
</listitem>
<listitem>
<para>
comparison_operator ::== |&gt; |&gt;= |&lt; |&lt;= |&lt;&gt;
</para>
</listitem>
<listitem>
<para>
arithmetic_expression ::= simple_arithmetic_expression |(subquery)
</para>
</listitem>
<listitem>
<para>
simple_arithmetic_expression ::= arithmetic_term | simple_arithmetic_expression
{+ |- } arithmetic_term
</para>
</listitem>
<listitem>
<para>
arithmetic_term ::= arithmetic_factor | arithmetic_term {* |/ }
arithmetic_factor
</para>
</listitem>
<listitem>
<para>
arithmetic_factor ::= [{+ |-}] arithmetic_primary
</para>
</listitem>
<listitem>
<para>
arithmetic_primary ::= state_field_path_expression | numeric_literal |
(simple_arithmetic_expression) | input_parameter | functions_returning_numerics
| aggregate_expression |
case_expression
</para>
</listitem>
<listitem>
<para>
string_expression ::= string_primary |(subquery)
</para>
</listitem>
<listitem>
<para>
string_primary ::= state_field_path_expression | string_literal |
input_parameter | functions_returning_strings | aggregate_expression |
case_expression
</para>
</listitem>
<listitem>
<para>
datetime_expression ::= datetime_primary |(subquery)
</para>
</listitem>
<listitem>
<para>
datetime_primary ::= state_field_path_expression | input_parameter |
functions_returning_datetime | aggregate_expression |
case_expression |
date_time_timestamp_literal
</para>
</listitem>
<listitem>
<para>
boolean_expression ::= boolean_primary |(subquery)
</para>
</listitem>
<listitem>
<para>
boolean_primary ::= state_field_path_expression | boolean_literal |
input_parameter |
case_expression
</para>
</listitem>
<listitem>
<para>
enum_expression ::= enum_primary |(subquery)
</para>
</listitem>
<listitem>
<para>
enum_primary ::= state_field_path_expression | enum_literal | input_parameter |
case_expression
</para>
</listitem>
<listitem>
<para>
entity_expression ::= single_valued_object_path_expression |
simple_entity_expression
</para>
</listitem>
<listitem>
<para>
simple_entity_expression ::= identification_variable | input_parameter
</para>
</listitem>
<listitem>
<para>
entity_type_expression ::=
type_discriminator |
entity_type_literal |
input_parameter
</para>
</listitem>
<listitem>
<para>
type_discriminator ::=
<literal>TYPE</literal>(identification_variable |
single_valued_object_path_expression |
input_parameter)
</para>
</listitem>
<listitem>
<para>
functions_returning_numerics ::= <literal>LENGTH</literal> (string_primary)|
<literal>LOCATE</literal> (string_primary,string_primary [,
simple_arithmetic_expression]) | <literal>ABS</literal>
(simple_arithmetic_expression) | <literal>SQRT</literal>
(simple_arithmetic_expression) | <literal>MOD</literal>
(simple_arithmetic_expression, simple_arithmetic_expression) | <literal>SIZE
</literal> (collection_valued_path_expression) |
<literal>INDEX</literal>(identification_variable)
</para>
</listitem>
<listitem>
<para>
functions_returning_datetime ::= <literal>CURRENT_DATE</literal> | <literal>
CURRENT_TIME</literal> | <literal>CURRENT_TIMESTAMP</literal>
</para>
</listitem>
<listitem>
<para>
functions_returning_strings ::= <literal>CONCAT</literal> (string_primary,
string_primary) | <literal>SUBSTRING</literal> (string_primary,
simple_arithmetic_expression[,simple_arithmetic_expression])| <literal>TRIM
</literal> ([[trim_specification] [trim_character] <literal>FROM</literal> ]
string_primary) | <literal>LOWER</literal> (string_primary) | <literal>UPPER
</literal> (string_primary)
</para>
</listitem>
<listitem>
<para>
trim_specification ::= <literal>LEADING</literal> | <literal>TRAILING</literal>
| <literal>BOTH</literal>
</para>
</listitem>
<listitem>
<para>
case_expression ::=
general_case_expression |
simple_case_expression |
coalesce_expression |
nullif_expression
</para>
</listitem>
<listitem>
<para>
general_case_expression::=
<literal>CASE</literal> when_clause {when_clause}* <literal>ELSE</literal> scalar_expression <literal>END</literal>
</para>
</listitem>
<listitem>
<para>
when_clause::= <literal>WHEN</literal> conditional_expression <literal>THEN</literal> scalar_expression
</para>
</listitem>
<listitem>
<para>
simple_case_expression::=
<literal>CASE</literal> case_operand simple_when_clause {simple_when_clause}*
<literal>ELSE</literal> scalar_expression
<literal>END</literal>
</para>
</listitem>
<listitem>
<para>
case_operand::= state_field_path_expression | type_discriminator
</para>
</listitem>
<listitem>
<para>
simple_when_clause::= <literal>WHEN</literal> scalar_expression <literal>THEN</literal> scalar_expression
</para>
</listitem>
<listitem>
<para>
coalesce_expression::= <literal>COALESCE</literal>(scalar_expression {, scalar_expression}+)
</para>
</listitem>
<listitem>
<para>
nullif_expression::= <literal>NULLIF</literal>(scalar_expression, scalar_expression)
</para>
</listitem>
</itemizedlist>
</section>
</section>
</chapter>