| <?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>jakarta.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<Magazine> results = (List<Magazine>) 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><> |
| </literal> tests for inequality. JPQL also supports the following arithmetic |
| operators for numeric comparisons: <literal>>, >=, <, <=</literal>. |
| For example: |
| </para> |
| <programlisting> |
| SELECT x FROM Magazine x WHERE x.price > 3.00 AND x.price <= 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 <> 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 > 3.00 AND x.price <= 5.00) OR x.price < 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 > 3.00 AND (x.price <= 5.00 OR x.price < 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 >= 3.00 AND x.price <= 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 <> 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) >= 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) >= 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 < 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 > ?2"); |
| q.setParameter(1, "JDJ").setParameter(2, 5.0); |
| List<Magazine> results = (List<Magazine>) 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 > :priceParam"); |
| q.setParameter("titleParam", "JDJ").setParameter("priceParam", 5.0); |
| List<Magazine> results = (List<Magazine>) 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 "openjpa.FetchPlan.ReadLockMode" on queries for entities that must be locked for serialization. |
| The value of <classname>ReadLockMode</classname> can be either "READ" or "WRITE". |
| 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 = "version") will result in the entity version field either being reread at end of transaction in the case of a value of "READ" or the version field updated at end of transaction in the case of "WRITE". 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 "openjpa.LockTimeout" or |
| "jakarta.persistence.lock.timeout" 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 "jakarta.persistence.query.timeout" |
| 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 "openjpa.hint.OptimizeResultCount" 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 "openjpa.FetchPlan.Isolation". The value will be used to specify isolation level using the SQL WITH <isolation> 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 "openjpa.FetchPlan."<property name>. 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 "openjpa.hint.MySQLSelectHint" and |
| "openjpa.hint.OracleSelectHint" 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> |
| jakarta.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("jakarta.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 > ?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<Magazine> results = (List<Magazine>) q.getResultList(); |
| </programlisting> |
| <programlisting> |
| EntityManager em = ... |
| Query q = em.createNamedQuery("magsByTitle"); |
| q.setParameter("titleParam", "JDJ"); |
| List<Magazine> results = (List<Magazine>) 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 < :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 < :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 > 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 > 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 > 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 > 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 > 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 > 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 < {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 > :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: =, >, >=, <, <=, <> (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 { =|<> } {boolean_expression | all_or_any_expression} | |
| enum_expression { =|<> } {enum_expression | all_or_any_expression} | |
| datetime_expression comparison_operator |
| {datetime_expression | all_or_any_expression} | |
| entity_expression { = | <> } {entity_expression | all_or_any_expression} | |
| arithmetic_expression comparison_operator |
| {arithmetic_expression | all_or_any_expression} | |
| entity_type_expression { = | <> } entity_type_expression} |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| comparison_operator ::= = | > | >= | < | <= | <> |
| </para> |
| </listitem> |
| </itemizedlist> |
| <para> |
| Examples: |
| </para> |
| <programlisting> |
| item.cost * 1.08 <= 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 <= x AND x <= 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 >= 15 AND p.age <= 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 < 15 OR p.age > 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 =, |
| <, <=, >, >=, <>. 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 >= 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) > 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 < (SELECT AVG(p.revenue) FROM Publisher p) |
| </programlisting> |
| <programlisting> |
| SELECT goodCustomer |
| FROM Customer goodCustomer |
| WHERE goodCustomer.balanceOwed < ( |
| 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 > 50000 THEN 'Platinum ' |
| WHEN f.annualMiles > 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) <> 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) > 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 > 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) > 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 > 5.00 |
| </programlisting> |
| <programlisting>SELECT NEW com.company.PublisherInfo(mag) |
| FROM Publisher pub JOIN pub.magazines mag WHERE mag.price > 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 > 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 < 1000000 AND 20 > (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 {=|<>} {boolean_expression | all_or_any_expression} | |
| enum_expression {=|<>} {enum_expression | all_or_any_expression} | |
| datetime_expression comparison_operator {datetime_expression | |
| all_or_any_expression} | entity_expression {= |<> } {entity_expression | |
| all_or_any_expression} | arithmetic_expression comparison_operator |
| {arithmetic_expression | all_or_any_expression} | |
| entity_type_expression { =|<>>} entity_type_expression} |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| comparison_operator ::== |> |>= |< |<= |<> |
| </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> |