| <?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_criteria"> |
| <title> |
| JPA Criteria |
| </title> |
| <indexterm zone="jpa_overview_criteria"> |
| <primary> |
| JP Criteria |
| </primary> |
| <seealso> |
| JPQL |
| </seealso> |
| </indexterm> |
| <indexterm> |
| <primary> |
| queries |
| </primary> |
| <see> |
| Query |
| </see> |
| </indexterm> |
| <para> |
| JPA 2.0 specification introduces a new API to define queries dynamically |
| via construction of an object-based |
| <classname>jakarta.persistence.CriteriaQuery</classname> instance, rather |
| than string-based approach used in JPQL (Java Persistence Query Language). |
| This dynamic query definition capability, referred as Criteria API, is |
| based on the abstract persistent schema of the entities, their embedded |
| objects and their relationships. The syntax is designed to construct a |
| <emphasis>Query Tree</emphasis> whose nodes represent the semantic query |
| elements such as projections, conditional predicates of WHERE clause or |
| GROUP BY elements etc. |
| </para> |
| |
| <section> |
| <title>Constructing a CriteriaQuery</title> |
| <para> |
| The CriteriaBuilder interface is the factory for CriteriaQuery. A |
| CriteriaBuilder is obtained from either an EntityManagerFactory or |
| an EntityManager as follows: |
| <programlisting> |
| EntityManager em = ... ; |
| CriteriaBuilder queryBuilder = em.getCriteriaBuilder(); |
| CriteriaQuery qdef = queryBuilder.createQuery(); |
| </programlisting> |
| The first step in constructing a query definition is specification of |
| query roots. Query roots specify the domain objects on which the query |
| is evaluated. Query root is an instance of the Root<T> interface. A |
| query root is added to a CriteriaQuery by |
| <methodname>addRoot(Class c)</methodname> method. |
| <programlisting> |
| Root<Customer> customer = qdef.from(Customer.class); |
| </programlisting> |
| A query domain can be further refined by joining to other domain objects. |
| For example, for the above query definition to operate over customers |
| and their orders, use <methodname>join(String attribute)</methodname>: |
| <programlisting> |
| Root<Order> order = customer.join(customer.get(Customer_.orders)); |
| </programlisting> |
| where Customer_.orders represent a field of canonical metamodel class for Customer. |
| These canonical metamodel classes are generated during compilation by processing |
| the persistent annotation in the source code of Customer.java. |
| </para> |
| <para> |
| The condition of a query definition is set via |
| <methodname>where(Predicate p)</methodname> where the argument |
| designates a conditional predicate. Conditional predicates are often |
| composed of one or more comparisons between the attribute values of |
| the domain objects and some variable. For example, to select the |
| Customer whose name is <emphasis>"John Doe"</emphasis> and has |
| orders that are not yet delivered, you can build the predicate and set |
| it to the query definition as: |
| <programlisting> |
| qdef.where(customer.get(Customer_.name).equal("John Doe") |
| .and(order.get(Order_.status).equal(OrderStatus.DELIVERED).not())); |
| </programlisting> |
| The <methodname>select()</methodname> method defines the result of the |
| query. If left unspecified, the select projection is assumed to be the |
| root domain object. However, you can specify the selected projections |
| explicitly as a list: |
| <programlisting> |
| qdef.select(customer.get(Customer_.name), order.get(Order_.status)); |
| </programlisting> |
| </para> |
| |
| <para> |
| An attribute of a domain object can also be specified by navigating via |
| <methodname>get(String attr)</methodname>. The attribute |
| <emphasis>should</emphasis> refer |
| to a valid persistent property of the receiving domain object, however |
| no such validation is enforced during the construction of the query |
| definition. All validation is deferred until the query is actually executed. |
| On the other hand, using canonical metamodel for path navigate enforces |
| compile type checking. |
| </para> |
| </section> |
| |
| <section> |
| <title>Executing a CriteriaQuery</title> |
| <para> |
| A CriteriaQuery is executed in a similar fashion to a string-based JPQL |
| query via the EntityManager and Query interfaces. |
| <programlisting> |
| EntityManager em = ... |
| Query query = em.createQuery(qdef); |
| List result = query.getResultList(); |
| </programlisting> |
| </para> |
| <para> |
| A query definition can use named parameters, and the parameter values are |
| set as usual in the Query instance. |
| </para> |
| |
| <para> |
| <ulink url="http://www.ibm.com/developerworks/java/library/j-typesafejpa/">A developerworks article</ulink> |
| explains details and further usage of Criteria API and its OpenJPA extensions. |
| </para> |
| </section> |
| |
| <section> |
| <title>Extension to Criteria API</title> |
| <para> |
| Criteria API has provided an alternative means to string-based JPQL to |
| execute a query. However, JPA 2.0 specification has not explicitly specified |
| any equivalence between a dynamically constructed CriteriaQuery and |
| a JPQL string. OpenJPA provides a mechanism to convert a CriteriaQuery to |
| an equivalent JPQL query string via the extended OpenJPACriteriaQuery API. |
| <programlisting> |
| public interface OpenJPACriteriaQuery extends CriteriaQuery { |
| /** |
| * Gets equivalent JPQL String for the given CriteriaQuery. |
| */ |
| public String toCQL(); |
| } |
| </programlisting> |
| |
| </para> |
| </section> |
| |
| <section> |
| <title>Generation of Canonical MetaModel classes</title> |
| <para> |
| Annotation processing tool generates source code for a metamodel class given |
| the annotated source code of persistent entity. |
| This tool is invoked during compilation for JDK6 compiler if OpenJPA and JPA |
| libraries are specified in the compiler <code>-classpath</code> option <emphasis>and</emphasis> |
| Annotation processor option <code>-Aopenjpa.metamodel=true</code> is specified. |
| <programlisting> |
| $ javac -classpath path/to/openjpa-all.jar -Aopenjpa.metamodel=true mypackage/MyEntity.java |
| </programlisting> |
| will generate source code for canonical meta-model class <code>mypackage.MyEntity_</code>. |
| The source code is generated relative to the directory specified in <code>-s</code> option |
| of <code>javac</code> compiler and defaulted to the current directory. |
| </para> |
| |
| <para> |
| The Annotation Processor recognizes the following options specified in the command-line with <code>-A</code> |
| (none of them are mandatory). |
| <itemizedlist> |
| <listitem> |
| <para> |
| -Aopenjpa.log=TRACE|INFO|WARN|ERROR : The logging level. Default is <code>WARN</code>. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| -Aopenjpa.source=<n> : where <n> denotes the integral number for Java source |
| version of the generated code. Default is <code>6</code>. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| -Aopenjpa.naming=class name : fully-qualified name of a class implementing |
| <code>org.apache.openjpa.meta.MetaDataFactory</code> that determines |
| the name of a meta-class given the name of the original persistent Java entity class. Defaults to |
| <code>org.apache.openjpa.persistence.PersistenceMetaDataFactory</code> which appends an underscore character |
| (<code>_</code>) to the original Java class name. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| -Aopenjpa.header=<url> : A url whose content will appear as comment header to the generated file(s). |
| Recognizes special value <code>ASL</code> for Apache Source License header as comment. |
| By default, adds an OpenJPA proprietary text as comment block. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| -Aopenjpa.addGeneratedAnnotation=auto|force|false : Configure whether the annotation |
| <code>jakarta.annotation.Generated</code> should be added to the generated metamodel classes. |
| This annotation is not available on Java 9 upwards unless the <code>jakarta.annotation-api</code> |
| is in the classpath. |
| The default is <code>auto</code>. Set to <code>force</code> to add the annotation even if it is |
| not in the classpath or to <code>false</code> to never add it to the generated class. |
| </para> |
| </listitem> |
| </itemizedlist> |
| </para> |
| </section> |
| |
| </chapter> |