HHH-4936 - Document JPA criteria queries

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18842 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Steve Ebersole 2010-02-19 21:16:50 +00:00
parent de0d4c1cd5
commit 84d1ac5f7d
2 changed files with 200 additions and 134 deletions

View File

@ -1,4 +1,4 @@
<?xml version='1.0' encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
@ -21,72 +21,67 @@
~ Free Software Foundation, Inc.
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
--><!-- This document was created with Syntext Serna Free. -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY versionNumber "3.4.0.GA">
<!ENTITY copyrightYear "2004">
<!ENTITY copyrightHolder "Red Hat Inc.">
]>
<book lang="en">
]>
<book>
<bookinfo>
<title>Hibernate EntityManager</title>
<subtitle>User guide</subtitle>
<releaseinfo>&versionNumber;</releaseinfo>
<mediaobject>
<imageobject>
<imagedata fileref="images/hibernate_logo_a.png" format="png" />
<imagedata fileref="images/hibernate_logo_a.png" format="PNG"/>
</imageobject>
</mediaobject>
</bookinfo>
<toc/>
<preface>
<title>Introducing EJB3 Persistence</title>
<para>The EJB3 specification recognizes the interest and the success of
the transparent object/relational mapping paradigm. The EJB3 specification
standardizes the basic APIs and the metadata needed for any
object/relational persistence mechanism. <emphasis>Hibernate
EntityManager</emphasis> implements the programming interfaces and
lifecycle rules as defined by the EJB3 persistence specification. Together
with <emphasis>Hibernate Annotations</emphasis>, this wrapper implements a
complete (and standalone) EJB3 persistence solution on top of the mature
Hibernate core. You may use a combination of all three together,
annotations without EJB3 programming interfaces and lifecycle, or even
pure native Hibernate, depending on the business and technical needs of
your project. You can at all times fall back to Hibernate native APIs, or
if required, even to native JDBC and SQL.</para>
</preface>
<xi:include href="modules/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/entitymanagerapi.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/listeners.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/batch.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/query_ejbql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/query_criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="modules/query_native.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
<bibliography>
<title>References</title>
<biblioentry id="JPA2">
<abbrev id="JPA2_ABBREV">JPA 2 Specification</abbrev>
<title>JSR 317: <trademark>Java</trademark> Persistence API, Version 2.0</title>
<collab>Java Persistence 2.0 Expert Group</collab>
<title>JSR 317: <trademark>Java</trademark> Persistence API, Version 2.0 </title>
<collab>
<collabname>Java Persistence 2.0 Expert Group</collabname>
</collab>
<copyright>
<year>2009</year>
<holder>SUN MICROSYSTEMS, INC.</holder>
</copyright>
<bibliomisc>
<email>jsr-317-feedback@sun.com</email>
<ulink url="http://jcp.org/en/jsr/detail?id=317"/>
<ulink url="http://jcp.org/en/jsr/detail?id=317">JSR 317 JCP Page</ulink>
</bibliomisc>
</biblioentry>
</bibliography>
<toc/>
<preface>
<title>Introducing EJB3 Persistence</title>
<para>The EJB3 specification recognizes the interest and the success of
the transparent object/relational mapping paradigm. The EJB3 specification
standardizes the basic APIs and the metadata needed for any
object/relational persistence mechanism.
<emphasis>Hibernate EntityManager</emphasis>
implements the programming interfaces and
lifecycle rules as defined by the EJB3 persistence specification. Together
with<emphasis>Hibernate Annotations</emphasis>, this wrapper implements a
complete (and standalone) EJB3 persistence solution on top of the mature
Hibernate core. You may use a combination of all three together,
annotations without EJB3 programming interfaces and lifecycle, or even
pure native Hibernate, depending on the business and technical needs of
your project. You can at all times fall back to Hibernate native APIs, or
if required, even to native JDBC and SQL.
</para>
</preface>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/architecture.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/configuration.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/entitymanagerapi.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/transactions.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/listeners.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/batch.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/query_ejbql.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/query_criteria.xml"/>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="modules/query_native.xml"/>
</book>

View File

@ -1,4 +1,4 @@
<?xml version='1.0' encoding="UTF-8"?>
<?xml version='1.0' encoding='UTF-8'?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
@ -22,17 +22,15 @@
~ 51 Franklin Street, Fifth Floor
~ Boston, MA 02110-1301 USA
-->
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
<chapter id="querycriteria">
<title>JPA Criteria Queries</title>
<title>Criteria Queries</title>
<note>
<para>
This chapter elaborates on the material discussed in
<citetitle pubwork="chapter">Chapter 6 Criteria API</citetitle> of the
<biblioref linkend="JPA2" endterm="JPA2_ABBREV" />.
<citetitle pubwork="chapter">Chapter 6 Criteria API</citetitle>
of<citation>JPA 2 Specification</citation>.
</para>
</note>
@ -41,54 +39,66 @@
in terms of using interfaces and classes to represent various structural parts of a query
such as the query itself, or the select clause, or an order-by, etc. They can also be
type-safe in terms of referencing attributes as we will see in a bit. Users of the older
Hibernate <interfacename>org.hibernate.Criteria</interfacename> query API will recognize
Hibernate
<interfacename>org.hibernate.Criteria</interfacename>
query API will recognize
the general approach, though we believe the JPA API to be superior as it represents a clean
look at the lessons learned from that API. There are essentially 2 phases to performing
a criteria query:
</para>
<orderedlist>
<listitem>
<para><link linkend="querycriteria-building">Building the criteria instance</link></para>
<para><link linkend="querycriteria-executing">Executing the criteria instance</link></para>
<para>
<link linkend="querycriteria-building">Building the criteria instance</link>
</para>
</listitem>
<listitem>
<para>
<link linkend="querycriteria-executing">Executing the criteria instance</link>
</para>
</listitem>
</orderedlist>
</para>
<section id="querycriteria-building">
<title>Criteria query building</title>
<para>
Criteria queries are essentially an object graph, where each part of the graph
represents an increasing (as we navigate down this graph) more atomic part of
query. The first step in performing a criteria query is building this graph.
</para>
<section id="querycriteria-builder">
<title>CriteriaBuilder</title>
<para>
The <interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename> interface is the
The
<interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename>
interface is the
first thing with which you need to become acquainted to begin using criteria queries. Its role
is a factory for all the individual pieces of the criteria. You obtain a
<interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename> instance by calling
the <methodname>javax.persistence.EntityManagerFactory.getCriteriaBuilder</methodname> method:
<interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename>
instance by calling
the
<methodname>javax.persistence.EntityManagerFactory.getCriteriaBuilder</methodname>
method:
</para>
<programlisting>CriteriaBuilder builder = entityManagerFactory.getCriteriaBuilder();</programlisting>
</section>
<section id="querycriteria-criteria">
<title>CriteriaQuery creation</title>
<para>
Once you have the <interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename> reference
Once you have the
<interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename>
reference
you can begin building the pieces of the criteria query. First, you will need a
<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename> instance.
<interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename> defines 3 methods
for obtaining a <interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>
<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>
instance.
<interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename>
defines 3 methods
for obtaining a
<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>
instance:
</para>
<itemizedlist>
<listitem>
<programlisting><![CDATA[CriteriaQuery<T> createQuery(Class<T>)]]></programlisting>
@ -100,80 +110,153 @@
<programlisting><![CDATA[CriteriaQuery<Object> createQuery()]]></programlisting>
</listitem>
</itemizedlist>
<para>
Each serves different purposes depending on the expected type of the query results. The type
is "carried forward" to the <interfacename>javax.persistence.TypedQuery</interfacename> we
create from this <interfacename>javax.persistence.criteria.CriteriaQuery</interfacename> as
we will see <link linkend="querycriteria-executing">later</link>.
Each serves a different purpose depending on the expected type of the query results. The type
is &quot;carried forward&quot; to the
<interfacename>javax.persistence.TypedQuery</interfacename>
we
create from this
<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>
as
we will see later in<xref linkend="querycriteria-executing"/>later.
</para>
<section id="querycriteria-criteria-typed">
<title>Typed CriteriaQuery</title>
<programlisting><![CDATA[CriteriaQuery<Person> personCriteria = builder.createQuery(Person.class);]]></programlisting>
<programlisting>
<![CDATA[CriteriaQuery<Person> personCriteria = builder.createQuery(Person.class);]]></programlisting>
<para>
Basically this is saying to create a criteria where the results of this query will be of type
Person. Person might be an entity or it might not. The type could even be simple types like
<classname>java.lang.Integer</classname>, <classname>java.lang.String</classname>, etc. We
will discuss this topic in more detail in <xref linkend="querycriteria-selection"/>
<classname>java.lang.Integer</classname>,<classname>java.lang.String</classname>, etc. We
will discuss this topic in more detail in
<xref linkend="querycriteria-selection"/>
</para>
</section>
<section id="querycriteria-criteria-tuple">
<title>Tuple CriteriaQuery</title>
<programlisting><![CDATA[CriteriaQuery<Tuple> personCriteria = builder.createTupleQuery();]]></programlisting>
<programlisting><![CDATA[CriteriaQuery<Tuple> personCriteria = builder.createQuery(Tuple.class);]]></programlisting>
<programlisting>
<![CDATA[CriteriaQuery<Tuple> personCriteria = builder.createTupleQuery();]]></programlisting>
<programlisting>
<![CDATA[CriteriaQuery<Tuple> personCriteria = builder.createQuery(Tuple.class);]]></programlisting>
<para>
These two forms are exactly the same. Both say to create a criteria where the results of this
query will be of type <interfacename>javax.persistence.Tuple</interfacename>. The term tuple is
query will be of type<interfacename>javax.persistence.Tuple</interfacename>. The term tuple is
taken from mathematics, but its intent here is simply to mean a plurality; namely we are saying
that each query result will actually be multiple values, a projection. The
<interfacename>javax.persistence.Tuple</interfacename> instance gives us typed access to these
<interfacename>javax.persistence.Tuple</interfacename>
instance gives us typed access to these
multiple result values after the query has been executed. We will discuss accessing the query
results via a <interfacename>javax.persistence.Tuple</interfacename> in
results via a
<interfacename>javax.persistence.Tuple</interfacename>
in
<xref linkend="querycriteria-executing"/>.
</para>
</section>
<section id="querycriteria-criteria-untyped">
<title>Untyped CriteriaQuery</title>
<programlisting><![CDATA[CriteriaQuery<Object> personCriteria = builder.createQuery();]]></programlisting>
<programlisting><![CDATA[CriteriaQuery<Object> personCriteria = builder.createQuery(Object.class);]]></programlisting>
<programlisting>
<![CDATA[CriteriaQuery<Object> personCriteria = builder.createQuery();]]></programlisting>
<programlisting>
<![CDATA[CriteriaQuery<Object> personCriteria = builder.createQuery(Object.class);]]></programlisting>
<para>
These two forms are exactly the same. Both say to create a criteria where the results of this
query could be anything. Not generally recommended as you obviously lose the type safety.
</para>
</section>
</section>
<section id="querycriteria-from">
<title>FROM clause</title>
<blockquote>
<attribution><biblioref linkend="JPA2" endterm="JPA2_ABBREV" /></attribution>
<attribution>
<citation>
<citation>JPA 2 Specification</citation>
</citation>
</attribution>
<para>
A CriteriaQuery object defines a query over one or more entity, embeddable, or basic abstract
schema types. The root objects of the query are entities, from which the other types are reached
by navigation.
</para>
</blockquote>
<para>All the individual parts of the FROM clause (roots, joins, paths) implement the
<interfacename>javax.persistence.criteria.From</interfacename>
interface.
</para>
<section id="querycriteria-from-root">
<title>Roots</title>
<para>
<para>Roots define the basis from which all joins, paths and attributes are available in the query. It
is
the root of the portion of your domain model you wish to query against. In a criteria query, a root
is always an entity. Roots are defined and added to the criteria by the overloaded
<methodname>from</methodname>
methods on<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>:
</para>
<programlisting><![CDATA[<X> Root<X> from(Class<X>)]]></programlisting>
<programlisting><![CDATA[<X> Root<X> from(EntityType<X>)]]></programlisting>
<programlisting><![CDATA[CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
// create and add the root
person.from( Person.class );
...]]></programlisting>
<para>Criteria queries may define multiple roots, the effect of which is to create a cartesean product
between the newly added root and the others. Here is an example matching all single men and all
single women:
</para>
<programlisting><![CDATA[CriteriaQuery query = builder.createQuery();
Root<Person> men = query.from( Person.class );
Root<Person> women = query.from( Person.class );
Predicate menRestriction = builder.and(
builder.equal(
men.get( Person_.gender ),
Gender.MALE
),
builder.equal(
men.get( Person_.relationshipStatus ),
RelationshipStatus.SINGLE
)
);
Predicate womenRestriction = builder.and(
builder.equal(
women.get( Person_.gender ),
Gender.FEMALE
),
builder.equal(
women.get( Person_.relationshipStatus ),
RelationshipStatus.SINGLE
)
);
query.where(
builder.and( menRestriction, womenRestriction )
);]]></programlisting>
</section>
<section id="querycriteria-from-join">
<title>Joins</title>
<para>todo</para>
<para>Joins allow navigation from other
<interfacename>javax.persistence.criteria.From</interfacename>
to either association or embedded attributes. Joins are created by the numerous overloaded
<methodname>join</methodname>
methods of the
<interfacename>javax.persistence.criteria.From</interfacename>
interface:
</para>
<programlisting><![CDATA[CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
Root<Person> personRoot = person.from( Person.class );
// Person.address is an embedded attribute
Join<Person,Address> personAddress = personRoot.join( Person_.address );
// Address.country is a ManyToOne
Join<Address,Country> addressCountry = personAddress.join( Address_.country );
...]]></programlisting>
<para>An example with collection attributes:</para>
<programlisting><![CDATA[CriteriaQuery<Person> personCriteria = builder.createQuery( Person.class );
Root<Person> personRoot = person.from( Person.class );
Join<Person,Order> orders = personRoot.join( Person_.orders );
Join<Order,LineItem> orderLines = orders.join( Order_.lineItems );
...]]></programlisting>
</section>
<section id="querycriteria-from-fetch">
<title>Fetches</title>
<para>todo</para>
</section>
</section>
<section id="querycriteria-path">
<title>Path expressions</title>
<note>
@ -183,22 +266,17 @@
</note>
<para>todo</para>
</section>
<section id="querycriteria-selection">
<title>Selections</title>
<para>todo</para>
</section>
</section>
<section id="querycriteria-executing">
<title>Criteria query execution</title>
<para>todo</para>
</section>
<section id="querycriteria-common">
<title>Common use cases</title>
<section id="querycriteria-common-selectroot">
<title>Selecting the root entity</title>
<programlisting><![CDATA[// get all people with brown eyes
@ -211,7 +289,6 @@ personCriteria.select( personRoot );
personCriteria.where( builder.equal( Person_.eyeColor, "brown" ) );
List<Person> people = em.createQuery( personCriteria ).getResultList();]]></programlisting>
</section>
<section id="querycriteria-common-selectassociation">
<title>Selecting an association</title>
<programlisting><![CDATA[// get the gender of all people with brown eyes
@ -224,7 +301,6 @@ personCriteria.select( personRoot );
personCriteria.where( builder.equal( Person_.eyeColor, "brown" ) );
List<Person> people = em.createQuery( personCriteria ).getResultList();]]></programlisting>
</section>
<section id="querycriteria-common-selectvalue">
<title>Selecting a value</title>
<programlisting><![CDATA[// get the height of all people with brown eyes
@ -234,7 +310,6 @@ personCriteria.select( personRoot.get( Person.height ) );
personCriteria.where( builder.equal( Person_.eyeColor, "brown" ) );
List<Integer> heights = em.createQuery( personCriteria ).getResultList();]]></programlisting>
</section>
<section id="querycriteria-common-selectaggregation">
<title>Selecting an aggregated value</title>
<programlisting><![CDATA[// get the maximum height of all people with brown eyes
@ -244,7 +319,6 @@ personCriteria.select( builder.max( personRoot.get( Person.height ) ) );
personCriteria.where( builder.equal( Person_.eyeColor, "brown" ) );
Integer maxHeight = em.createQuery( personCriteria ).getSingleResult();]]></programlisting>
</section>
<section id="querycriteria-common-selecttuple">
<title>Selecting a tuple</title>
<programlisting><![CDATA[// get the id, height and gender of all people with brown eyes
@ -266,7 +340,6 @@ for ( Tuple tuple : tuples ) {
handleId( tuple.get( "id" ) );
}]]></programlisting>
</section>
<section id="querycriteria-common-selectconstruct">
<title>Selecting a constructed value</title>
<programlisting><![CDATA[// get the id, height and gender of all people with brown eyes
@ -283,7 +356,6 @@ personCriteria.select(
);
List<PersonHolder> people = em.createQuery( personCriteria ).getResultList();]]></programlisting>
</section>
<section id="querycriteria-common-param">
<title>Using parameters</title>
<programlisting><![CDATA[// get all people with brown eyes
@ -297,5 +369,4 @@ query.setParameter( eyeColorParam, "brown" );
List<Person> people = query.getResultList();]]></programlisting>
</section>
</section>
</chapter>