HHH-4933 finish documentation on JPA 2 and EntityManager, migrate to jHighlight

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18956 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Emmanuel Bernard 2010-03-10 10:56:16 +00:00
parent a284638d01
commit 3153fb385d
9 changed files with 309 additions and 142 deletions

View File

@ -70,6 +70,12 @@
<surname>Ebersole</surname>
</author>
<author>
<firstname>Gavin</firstname>
<surname>King</surname>
</author>
<!--TODO add translators like core did -->
</authorgroup>
</bookinfo>

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,8 +22,8 @@
~ 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="batch">
<title>Batch processing</title>
@ -34,7 +34,7 @@
Hibernate reference guide, however, EJB3 persistence differs
slightly.</para>
<sect1 id="batch-direct">
<section id="batch-direct">
<title>Bulk update/delete</title>
<para>As already discussed, automatic and transparent object/relational
@ -44,7 +44,7 @@
directly in the database will not affect in-memory state. However,
Hibernate provides methods for bulk SQL-style <literal>UPDATE</literal>
and <literal>DELETE</literal> statement execution which are performed
through EJB-QL (<xref linkend="queryhql" />).</para>
through JP-QL (<xref linkend="queryhql" />).</para>
<para>The pseudo-syntax for <literal>UPDATE</literal> and
<literal>DELETE</literal> statements is: <literal>( UPDATE | DELETE )
@ -63,7 +63,7 @@
<listitem>
<para>No joins (either implicit or explicit) can be specified in a
bulk EJB-QL query. Sub-queries may be used in the where-clause.</para>
bulk JP-QL query. Sub-queries may be used in the where-clause.</para>
</listitem>
<listitem>
@ -71,26 +71,26 @@
</listitem>
</itemizedlist>
<para>As an example, to execute an EJB-QL <literal>UPDATE</literal>, use
<para>As an example, to execute an JP-QL <literal>UPDATE</literal>, use
the <literal>Query.executeUpdate()</literal> method:</para>
<programlisting>EntityManager entityManager = entityManagerFactory.createEntityManager();
<programlisting role="JAVA" language="JAVA">EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
String ejbqlUpdate = "update Customer set name = :newName where name = :oldName"
int updatedEntities = entityManager.createQuery( ejbqlUpdate )
String jpqlUpdate = "update Customer set name = :newName where name = :oldName"
int updatedEntities = entityManager.createQuery( jpqlUpdate )
.setParameter( "newName", newName )
.setParameter( "oldName", oldName )
.executeUpdate();
entityManager.getTransaction().commit();
entityManager.close();</programlisting>
<para>To execute an EJB-QL <literal>DELETE</literal>, use the same
<para>To execute an JP-QL <literal>DELETE</literal>, use the same
<literal>Query.executeUpdate()</literal> method (the method is named for
those familiar with JDBC's
<literal>PreparedStatement.executeUpdate()</literal>):</para>
<programlisting>EntityManager entityManager = entityManagerFactory.createEntityManager();
<programlisting role="JAVA" language="JAVA">EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
String hqlDelete = "delete Customer where name = :oldName";
@ -103,13 +103,13 @@ entityManager.close();</programlisting>
<para>The <literal>int</literal> value returned by the
<literal>Query.executeUpdate()</literal> method indicate the number of
entities effected by the operation. This may or may not correlate with the
number of rows effected in the database. An EJB-QL bulk operation might
number of rows effected in the database. A JP-QL bulk operation might
result in multiple actual SQL statements being executed, for
joined-subclass, for example. The returned number indicates the number of
actual entities affected by the statement. Going back to the example of
joined-subclass, a delete against one of the subclasses may actually
result in deletes against not just the table to which that subclass is
mapped, but also the "root" table and potentially joined-subclass tables
further down the inheritence hierarchy.</para>
</sect1>
</chapter>
further down the inheritance hierarchy.</para>
</section>
</chapter>

View File

@ -669,10 +669,10 @@ EntityManagerFactory programmaticEmf =
&lt;class&gt;org.hibernate.ejb.test.Distributor&lt;/class&gt;
&lt;class&gt;org.hibernate.ejb.test.Item&lt;/class&gt;
&lt;properties&gt;
&lt;property name="<literal>javax.persistence.jdbc.driver</literal>" value="org.hsqldb.jdbcDriver"/&gt;
&lt;property name="<literal>javax.persistence.jdbc.user</literal>" value="sa"/&gt;
&lt;property name="<literal>javax.persistence.jdbc.password</literal>" value=""/&gt;
&lt;property name="<literal>javax.persistence.jdbc.url</literal>" value="jdbc:hsqldb:."/&gt;
&lt;property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/&gt;
&lt;property name="javax.persistence.jdbc.user" value="sa"/&gt;
&lt;property name="javax.persistence.jdbc.password" value=""/&gt;
&lt;property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:."/&gt;
&lt;property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/
&lt;property name="hibernate.max_fetch_depth" value="3"/&gt;
@ -857,7 +857,7 @@ EntityManagerFactory emf =
<classname>Persistence</classname> class is bootstrap class to create an
entity manager factory.</para>
<programlisting role="JAVA" language="JAVA">// Use persistence.xml configuration
<programlisting role="JAVA" language="JAVA">// Use persistence.xml configuration
EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1")
EntityManager em = emf.createEntityManager(); // Retrieve an application managed entity manager
// Work with the EM

View File

@ -74,7 +74,7 @@
<literal>new</literal> operator) it is in <literal>new</literal> state.
You can make it persistent by associating it to an entity manager:</para>
<programlisting>DomesticCat fritz = new DomesticCat();
<programlisting language="JAVA" role="JAVA">DomesticCat fritz = new DomesticCat();
fritz.setColor(Color.GINGER);
fritz.setSex('M');
fritz.setName("Fritz");
@ -93,7 +93,7 @@ em.persist(fritz);</programlisting>
<para>Load an entity instance by its identifier value with the entity
manager's <code>find()</code> method:</para>
<programlisting>cat = em.find(Cat.class, catId);
<programlisting language="JAVA" role="JAVA">cat = em.find(Cat.class, catId);
// You may need to wrap the primitive identifiers
long catId = 1234;
@ -105,7 +105,7 @@ em.find( Cat.class, new Long(catId) );</programlisting>
useful to link a child to its parent without having to load the
parent.</para>
<programlisting>child = new Child();
<programlisting language="JAVA" role="JAVA">child = new Child();
child.SetName("Henry");
Parent parent = em.getReference(Parent.class, parentId); //no query to the DB
child.setParent(parent);
@ -118,7 +118,7 @@ em.persist(child);</programlisting>
refreshed unless you specify <literal>REFRESH</literal> as a cascade style
of any associations:</para>
<programlisting>em.persist(cat);
<programlisting language="JAVA" role="JAVA">em.persist(cat);
em.flush(); // force the SQL insert and triggers to run
em.refresh(cat); //re-read the state (after the trigger executes)</programlisting>
</section>
@ -145,7 +145,7 @@ em.refresh(cat); //re-read the state (after the trigger executes)</programlistin
the query. Queries are always created using the current entity
manager:</para>
<programlisting>List&lt;?&gt; cats = em.createQuery(
<programlisting language="JAVA" role="JAVA">List&lt;?&gt; cats = em.createQuery(
"select cat from Cat as cat where cat.birthdate &lt; ?1")
.setParameter(1, date, TemporalType.DATE)
.getResultList();
@ -176,7 +176,7 @@ Cat mother = (Cat) em.createQuery(
type-safe approach is the Criteria API explained in <xref
linkend="querycriteria" />.</para>
<programlisting>CriteriaQuery&lt;Cat&gt; criteria = builder.createQuery( Cat.class );
<programlisting language="JAVA" role="JAVA">CriteriaQuery&lt;Cat&gt; criteria = builder.createQuery( Cat.class );
Root&lt;Cat&gt; cat = criteria.from( Cat.class );
criteria.select( cat );
criteria.where( builder.lt( cat.get( Cat_.birthdate ), catDate ) );
@ -186,7 +186,7 @@ List&lt;Cat&gt; cats = em.createQuery( criteria ).getResultList(); //notice no d
using JP-QL (note that it's not as type-safe as the compiler has to
trust you with the return type.</para>
<programlisting>//No downcasting since we pass the return type
<programlisting language="JAVA" role="JAVA">//No downcasting since we pass the return type
List&lt;Cat&gt; cats = em.createQuery(
"select cat from Cat as cat where cat.birthdate &lt; ?1", Cat.class)
.setParameter(1, date, TemporalType.DATE)
@ -205,7 +205,7 @@ List&lt;Cat&gt; cats = em.createQuery(
<para>JPA queries can return tuples of objects if projection is used.
Each result tuple is returned as an object array:</para>
<programlisting>Iterator kittensAndMothers = sess.createQuery(
<programlisting language="JAVA" role="JAVA">Iterator kittensAndMothers = sess.createQuery(
"select kitten, mother from Cat kitten join kitten.mother mother")
.getResultList()
.iterator();
@ -233,7 +233,7 @@ while ( kittensAndMothers.hasNext() ) {
persistent state (in other words, they are considered "read
only"):</para>
<programlisting>Iterator results = em.createQuery(
<programlisting language="JAVA" role="JAVA">Iterator results = em.createQuery(
"select cat.color, min(cat.birthdate), count(cat) from Cat cat " +
"group by cat.color")
.getResultList()
@ -258,7 +258,7 @@ while ( results.hasNext() ) {
in the query string. Named parameters should be preferred, they are
more robust and easier to read and understand:</para>
<programlisting>// Named parameter (preferred)
<programlisting language="JAVA" role="JAVA">// Named parameter (preferred)
Query q = em.createQuery("select cat from DomesticCat cat where cat.name = :name");
q.setParameter("name", "Fritz");
List cats = q.getResultList();
@ -284,7 +284,7 @@ List cats = q.list();</programlisting>
number of rows you want to retrieve and/or the first row you want to
retrieve), use the following methods:</para>
<programlisting>Query q = em.createQuery("select cat from DomesticCat cat");
<programlisting language="JAVA" role="JAVA">Query q = em.createQuery("select cat from DomesticCat cat");
q.setFirstResult(20);
q.setMaxResults(10);
List cats = q.getResultList(); //return cats from the 20th position to 29th</programlisting>
@ -298,20 +298,20 @@ List cats = q.getResultList(); //return cats from the 20th position to 29th</pro
<para>You may also define named queries through annotations:</para>
<programlisting>@javax.persistence.NamedQuery(name="eg.DomesticCat.by.name.and.minimum.weight",
<programlisting language="JAVA" role="JAVA">@javax.persistence.NamedQuery(name="eg.DomesticCat.by.name.and.minimum.weight",
query="select cat from eg.DomesticCat as cat where cat.name = ?1 and cat.weight &gt; ?2")</programlisting>
<para>Parameters are bound programmatically to the named query, before
it is executed:</para>
<programlisting>Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight");
<programlisting language="JAVA" role="JAVA">Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight");
q.setString(1, name);
q.setInt(2, minWeight);
List&lt;?&gt; cats = q.getResultList();</programlisting>
<para>You can also use the slightly more type-safe approach:</para>
<programlisting>Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight", Cat.class);
<programlisting language="JAVA" role="JAVA">Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight", Cat.class);
q.setString(1, name);
q.setInt(2, minWeight);
List&lt;Cat&gt; cats = q.getResultList();</programlisting>
@ -335,7 +335,7 @@ List&lt;Cat&gt; cats = q.getResultList();</programlisting>
remember that all entity columns have to be returned for this
mechanism to work):</para>
<programlisting>@SqlResultSetMapping(name="getItem", entities =
<programlisting language="JAVA" role="JAVA">@SqlResultSetMapping(name="getItem", entities =
@EntityResult(entityClass=org.hibernate.ejb.test.Item.class, fields= {
@FieldResult(name="name", column="itemname"),
@FieldResult(name="descr", column="itemdescription")
@ -358,7 +358,7 @@ item = (Item) q.getSingleResult(); //from a class columns names match the mappin
<title>Query lock and flush mode</title>
<para>You can adjust the flush mode used when executing the query as
well as define the lock mode used to load the entities. </para>
well as define the lock mode used to load the entities.</para>
<para>Adjusting the flush mode is interesting when one must guaranty
that a query execution will not trigger a flush operation. Most of the
@ -367,7 +367,7 @@ item = (Item) q.getSingleResult(); //from a class columns names match the mappin
<para>Adjusting the lock mode is useful if you need to lock the
objects returns by the query to a certain level.</para>
<programlisting>query.setFlushMode(FlushModeType.COMMIT)
<programlisting language="JAVA" role="JAVA">query.setFlushMode(FlushModeType.COMMIT)
.setLockMode(LockModeType.PESSIMISTIC_READ);</programlisting>
<note>
@ -492,7 +492,7 @@ item = (Item) q.getSingleResult(); //from a class columns names match the mappin
<methodname>find()</methodname> it, and then manipulate it directly, while
the persistence context is open:</para>
<programlisting>Cat cat = em.find( Cat.class, new Long(69) );
<programlisting language="JAVA" role="JAVA">Cat cat = em.find( Cat.class, new Long(69) );
cat.setName("PK");
em.flush(); // changes to cat are automatically detected and persisted</programlisting>
@ -510,7 +510,7 @@ em.flush(); // changes to cat are automatically detected and persisted</program
by Hibernate) by closing the EntityManager or in a more fine-grained
approach by calling the <methodname>detach()</methodname> method.</para>
<programlisting>Cat cat = em.find( Cat.class, new Long(69) );
<programlisting language="JAVA" role="JAVA">Cat cat = em.find( Cat.class, new Long(69) );
...
em.detach(cat);
cat.setName("New name"); //not propatated to the database</programlisting>
@ -530,7 +530,7 @@ cat.setName("New name"); //not propatated to the database</programlisting>
for persistence of modifications made to detached instances using the
<methodname>EntityManager.merge()</methodname> method:</para>
<programlisting>// in the first entity manager
<programlisting language="JAVA" role="JAVA">// in the first entity manager
Cat cat = firstEntityManager.find(Cat.class, catId);
Cat potentialMate = new Cat();
firstEntityManager.persist(potentialMate);
@ -563,7 +563,7 @@ secondEntityManager.merge(mate); // update mate</programlisting>
not a detached instance) to <literal>merge()</literal>, the entity manager
will figure this out for you:</para>
<programlisting>// In the first entity manager
<programlisting language="JAVA" role="JAVA">// In the first entity manager
Cat cat = firstEntityManager.find(Cat.class, catID);
// In a higher layer of the application, detached
@ -739,7 +739,7 @@ secondEntityManager.merge(mate); // save the new instance</programlisting>
automatically using the explained routine unless
<methodname>flush()</methodname> is called explicitly.</para>
<programlisting>em = emf.createEntityManager();
<programlisting language="JAVA" role="JAVA">em = emf.createEntityManager();
Transaction tx = em.getTransaction().begin();
em.setFlushMode(FlushModeType.COMMIT); // allow queries to return stale state
@ -817,11 +817,11 @@ em.getTransaction().commit(); // flush occurs</programlisting>
associated entity (or collection of entities), you must indicate that in
the association annotation:</para>
<programlisting>@OneToOne(cascade=CascadeType.PERSIST)</programlisting>
<programlisting language="JAVA" role="JAVA">@OneToOne(cascade=CascadeType.PERSIST)</programlisting>
<para>Cascading options can be combined:</para>
<programlisting>@OneToOne(cascade= { CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH } )</programlisting>
<programlisting language="JAVA" role="JAVA">@OneToOne(cascade= { CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH } )</programlisting>
<para>You may even use <literal>CascadeType.ALL</literal> to specify that
all operations should be cascaded for a particular association. Remember
@ -924,4 +924,137 @@ em.getTransaction().commit(); // flush occurs</programlisting>
nobody changes the data underneath while pessimistic locks enforce the
lock right away and keep it till the transaction is committed.</para>
</section>
<section>
<title>Caching</title>
<para>When the second-level cache is activated (see <xref
linkend="setup-configuration-packaging" /> and the Hibernate Annotations
reference documentation), Hibernate ensures it is used and properly
updated. You can however adjust these settings by passing two
properties:</para>
<itemizedlist>
<listitem>
<para><literal>javax.persistence.cache.retrieveMode</literal> which
accepts <literal><classname>CacheRetrieveMode</classname></literal>
values</para>
</listitem>
<listitem>
<para><literal>javax.persistence.cache.storeMode</literal> which
accepts <classname>CacheStoreMode</classname> values</para>
</listitem>
</itemizedlist>
<para><classname>CacheRetrieveMode</classname> controls how Hibernate
accesses information from the second-level cache: <literal>USE</literal>
which is the default or <literal>BYPASS</literal> which means ignore the
cache. <classname>CacheStoreMode</classname> controls how Hibernate pushes
information to the second-level cache: <literal>USE</literal> which is the
default and push data in the cache when reading from and writing to the
database, <literal>BYPASS</literal> which does not insert new data in the
cache (but can invalidate obsolete data) and
<classname>REFRESH</classname> which does like default but also force data
to be pushed to the cache on database read even if the data is already
cached.</para>
<para>You can set these properties:</para>
<itemizedlist>
<listitem>
<para>on a particular <classname>EntityManager</classname> via the
<methodname>setProperty</methodname> method</para>
</listitem>
<listitem>
<para>on a query via a query hint (<methodname>setHint</methodname>
method)</para>
</listitem>
<listitem>
<para>when calling <methodname>find()</methodname> and
<methodname>refresh()</methodname> and passing the properties in the
appropriate <classname>Map</classname></para>
</listitem>
</itemizedlist>
<para>JPA also introduces an API to interrogate the second-level cache and
evict data manually.</para>
<programlisting language="JAVA" role="JAVA">Cache cache = entityManagerFactory.getCache();
if ( cache.contains(User.class, userId) ) {
//load it as we don't hit the DB
}
cache.evict(User.class, userId); //manually evict user form the second-level cache
cache.evict(User.class); //evict all users from the second-level cache
cache.evictAll(); //purge the second-level cache entirely</programlisting>
</section>
<section>
<title>Checking the state of an object</title>
<para>You can check whether an object is managed by the persistence
context</para>
<programlisting language="JAVA" role="JAVA">entityManager.get(Cat.class, catId);
...
boolean isIn = entityManager.contains(cat);
assert isIn;</programlisting>
<para>You can also check whether an object, an association or a property
is lazy or not. You can do that independently of the underlying
persistence provider: </para>
<programlisting language="JAVA" role="JAVA">PersistenceUtil jpaUtil = Persistence.getPersistenceUtil();
if ( jpaUtil.isLoaded( customer.getAddress() ) {
//display address if loaded
}
if ( jpaUtil.isLoaded( customer.getOrders ) ) {
//display orders if loaded
}
if (jpaUtil.isLoaded(customer, "detailedBio") ) {
//display property detailedBio if loaded
}</programlisting>
<para>However, if you have access to the entityManagerFactory, we
recommend you to use:</para>
<programlisting language="JAVA" role="JAVA">PersistenceUnitUtil jpaUtil = entityManager.getEntityManagerFactory().getPersistenceUnitUtil();
Customer customer = entityManager.get( Customer.class, customerId );
if ( jpaUtil.isLoaded( customer.getAddress() ) {
//display address if loaded
}
if ( jpaUtil.isLoaded( customer.getOrders ) ) {
//display orders if loaded
}
if (jpaUtil.isLoaded(customer, "detailedBio") ) {
//display property detailedBio if loaded
}
log.debug( "Customer id {}", jpaUtil.getIdentifier(customer) );</programlisting>
<para>The performances are likely to be slightly better and you can get
the identifier value from an object (using
<methodname>getIdentifier()</methodname>).</para>
<note>
<para>These are roughly the counterpart methods of
<methodname>Hibernate.isInitialize</methodname>.</para>
</note>
</section>
<section>
<title>Native Hibernate API</title>
<para>You can always fall back to the underlying
<classname>Session</classname> API from a given
<classname>EntityManager</classname>:</para>
<programlisting language="JAVA" role="JAVA">Session session = entityManager.unwrap(Session.class);</programlisting>
</section>
</chapter>

View File

@ -45,7 +45,7 @@
entity class with the <literal>@EntityListeners</literal>
annotation:</para>
<programlisting>@Entity
<programlisting role="JAVA" language="JAVA">@Entity
@EntityListeners(class=Audit.class)
public class Cat {
@Id private Integer id;
@ -221,7 +221,7 @@ public class LastUpdateListener {
deployment descriptors. There is also an additional feature that can be
useful: default event listeners.</para>
<programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
<programlisting role="XML" language="XML">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

View File

@ -49,7 +49,7 @@
of the
<interfacename>javax.persistence.EntityManagerFactory</interfacename></para>
<programlisting>CriteriaBuilder builder = entityManagerFactory.getCriteriaBuilder();</programlisting>
<programlisting role="JAVA" language="JAVA">CriteriaBuilder builder = entityManagerFactory.getCriteriaBuilder();</programlisting>
<para>The next step is to obtain a
<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>. You
@ -57,11 +57,11 @@
<interfacename>javax.persistence.criteria.CriteriaBuilder</interfacename>
for this purpose.</para>
<programlisting>CriteriaQuery&lt;T&gt; createQuery(Class&lt;T&gt;)</programlisting>
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;T&gt; createQuery(Class&lt;T&gt;)</programlisting>
<programlisting>CriteriaQuery&lt;Tuple&gt; createTupleQuery()</programlisting>
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Tuple&gt; createTupleQuery()</programlisting>
<programlisting>CriteriaQuery&lt;Object&gt; createQuery()</programlisting>
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Object&gt; createQuery()</programlisting>
<para>Each serves a different purpose depending on the expected type of the
query results.</para>
@ -77,7 +77,7 @@
<section id="querycriteria-typedquery">
<title>Typed criteria queries</title>
<programlisting>CriteriaQuery&lt;T&gt; createQuery(Class&lt;T&gt;)</programlisting>
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;T&gt; createQuery(Class&lt;T&gt;)</programlisting>
<para>The type of the criteria query (aka the &lt;T&gt;) indicates the
expected types in the query result. This might be an entity, an Integer,
@ -106,7 +106,7 @@
<area coords="4" id="ex.criteria.typedquery.entity.3" />
</areaspec>
<programlisting>CriteriaQuery&lt;Person&gt; criteria = builder.createQuery( Person.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Person&gt; criteria = builder.createQuery( Person.class );
Root&lt;Person&gt; personRoot = criteria.from( Person.class );
criteria.select( personRoot );
criteria.where( builder.equal( personRoot.get( Person_.eyeColor ), "brown" ) );
@ -160,7 +160,7 @@ for ( Person person : people ) { ... }</programlisting>
<area coords="3" id="ex.criteria.typedquery.attr.2" />
</areaspec>
<programlisting>CriteriaQuery&lt;Integer&gt; criteria = builder.createQuery( Integer.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Integer&gt; criteria = builder.createQuery( Integer.class );
Root&lt;Person&gt; personRoot = criteria.from( Person.class );
criteria.select( personRoot.get( Person_.age ) );
criteria.where( builder.equal( personRoot.get( Person_.eyeColor ), "brown" ) );
@ -195,7 +195,7 @@ for ( Integer age : ages ) { ... } </programlisting>
<area coords="3" id="ex.criteria.typedquery.expr.1" />
</areaspec>
<programlisting>CriteriaQuery&lt;Integer&gt; criteria = builder.createQuery( Integer.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Integer&gt; criteria = builder.createQuery( Integer.class );
Root&lt;Person&gt; personRoot = criteria.from( Person.class );
criteria.select( builder.max( personRoot.get( Person_.age ) ) );
criteria.where( builder.equal( personRoot.get( Person_.eyeColor ), "brown" ) );
@ -239,7 +239,7 @@ Integer maxAge = em.createQuery( criteria ).getSingleResult();</programlisting>
<area coords="5" id="ex.criteria.typedquery.array.2" />
</areaspec>
<programlisting>CriteriaQuery&lt;Object[]&gt; criteria = builder.createQuery( Object[].class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Object[]&gt; criteria = builder.createQuery( Object[].class );
Root&lt;Person&gt; personRoot = criteria.from( Person.class );
Path&lt;Long&gt; idPath = personRoot.get( Person_.id );
Path&lt;Integer&gt; agePath = personRoot.get( Person_.age );
@ -284,7 +284,7 @@ for ( Object[] values : valueArray ) {
<area coords="5" id="ex.criteria.typedquery.array2.2" />
</areaspec>
<programlisting>CriteriaQuery&lt;Object[]&gt; criteria = builder.createQuery( Object[].class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Object[]&gt; criteria = builder.createQuery( Object[].class );
Root&lt;Person&gt; personRoot = criteria.from( Person.class );
Path&lt;Long&gt; idPath = personRoot.get( Person_.id );
Path&lt;Integer&gt; agePath = personRoot.get( Person_.age );
@ -351,7 +351,7 @@ for ( Object[] values : valueArray ) {
</areaset>
</areaspec>
<programlisting>public class PersonWrapper {
<programlisting role="JAVA" language="JAVA">public class PersonWrapper {
private final Long id;
private final Integer age;
public PersonWrapper(Long id, Integer age) {
@ -433,7 +433,7 @@ for ( PersonWrapper person : people ) { ... }</programlisting>
</areaset>
</areaspec>
<programlisting>CriteriaQuery&lt;Tuple&gt; criteria = builder.createTupleQuery();
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Tuple&gt; criteria = builder.createTupleQuery();
Root&lt;Person&gt; personRoot = criteria.from( Person.class );
Path&lt;Long&gt; idPath = personRoot.get( Person_.id );
Path&lt;Integer&gt; agePath = personRoot.get( Person_.age );
@ -493,7 +493,7 @@ for ( Tuple tuple : valueArray ) {
<term>typed</term>
<listitem>
<programlisting>&lt;X&gt; X get(TupleElement&lt;X&gt; tupleElement)</programlisting>
<programlisting role="JAVA" language="JAVA">&lt;X&gt; X get(TupleElement&lt;X&gt; tupleElement)</programlisting>
<para>This allows typed access to the underlying tuple elements.
We see this in <xref linkend="ex-criteria-typedquery-tuple" /> in
@ -508,9 +508,9 @@ for ( Tuple tuple : valueArray ) {
<term>positional</term>
<listitem>
<programlisting>Object get(int i)</programlisting>
<programlisting role="JAVA" language="JAVA">Object get(int i)</programlisting>
<programlisting>&lt;X&gt; X get(int i, Class&lt;X&gt; type)</programlisting>
<programlisting role="JAVA" language="JAVA">&lt;X&gt; X get(int i, Class&lt;X&gt; type)</programlisting>
<para>Very similar to what we saw in <xref
linkend="ex-criteria-typedquery-array" /> and <xref
@ -527,9 +527,9 @@ for ( Tuple tuple : valueArray ) {
<term>aliased</term>
<listitem>
<programlisting>Object get(String alias)</programlisting>
<programlisting role="JAVA" language="JAVA">Object get(String alias)</programlisting>
<programlisting>&lt;X&gt; X get(String alias, Class&lt;X&gt; type)</programlisting>
<programlisting role="JAVA" language="JAVA">&lt;X&gt; X get(String alias, Class&lt;X&gt; type)</programlisting>
<para>Again, only the second form here provides typing, because
the user explicitly provides the typing on access. We have not
@ -574,14 +574,14 @@ for ( Tuple tuple : valueArray ) {
<methodname>from</methodname> methods on
<interfacename>javax.persistence.criteria.CriteriaQuery</interfacename>:</para>
<programlisting>&lt;X&gt; Root&lt;X&gt; from(Class&lt;X&gt;)</programlisting>
<programlisting role="JAVA" language="JAVA">&lt;X&gt; Root&lt;X&gt; from(Class&lt;X&gt;)</programlisting>
<programlisting>&lt;X&gt; Root&lt;X&gt; from(EntityType&lt;X&gt;)</programlisting>
<programlisting role="JAVA" language="JAVA">&lt;X&gt; Root&lt;X&gt; from(EntityType&lt;X&gt;)</programlisting>
<example>
<title>Adding a root</title>
<programlisting>CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
// create and add the root
person.from( Person.class );
...</programlisting>
@ -593,7 +593,7 @@ person.from( Person.class );
product</ulink> between the newly added root and the others. Here is an
example matching all single men and all single women:</para>
<programlisting>CriteriaQuery query = builder.createQuery();
<programlisting role="JAVA" language="JAVA">CriteriaQuery query = builder.createQuery();
Root&lt;Person&gt; men = query.from( Person.class );
Root&lt;Person&gt; women = query.from( Person.class );
Predicate menRestriction = builder.and(
@ -620,7 +620,7 @@ query.where( builder.and( menRestriction, womenRestriction ) );</programlisting>
<example id="criteria-join-singular">
<title>Example with Embedded and ManyToOne</title>
<programlisting>CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
Root&lt;Person&gt; personRoot = person.from( Person.class );
// Person.address is an embedded attribute
Join&lt;Person,Address&gt; personAddress = personRoot.join( Person_.address );
@ -632,7 +632,7 @@ Join&lt;Address,Country&gt; addressCountry = personAddress.join( Address_.countr
<example id="criteria-join-plural">
<title>Example with Collections</title>
<programlisting>CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
Root&lt;Person&gt; personRoot = person.from( Person.class );
Join&lt;Person,Order&gt; orders = personRoot.join( Person_.orders );
Join&lt;Order,LineItem&gt; orderLines = orders.join( Order_.lineItems );
@ -652,7 +652,7 @@ Join&lt;Order,LineItem&gt; orderLines = orders.join( Order_.lineItems );
<example id="criteria-fetch-singular">
<title>Example with Embedded and ManyToOne</title>
<programlisting>CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
Root&lt;Person&gt; personRoot = person.from( Person.class );
// Person.address is an embedded attribute
Join&lt;Person,Address&gt; personAddress = personRoot.fetch( Person_.address );
@ -672,7 +672,7 @@ Join&lt;Address,Country&gt; addressCountry = personAddress.fetch( Address_.count
<example id="criteria-fetch-plural">
<title>Example with Collections</title>
<programlisting>CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Person&gt; personCriteria = builder.createQuery( Person.class );
Root&lt;Person&gt; personRoot = person.from( Person.class );
Join&lt;Person,Order&gt; orders = personRoot.fetch( Person_.orders );
Join&lt;Order,LineItem&gt; orderLines = orders.fetch( Order_.lineItems );
@ -704,7 +704,7 @@ Join&lt;Order,LineItem&gt; orderLines = orders.fetch( Order_.lineItems );
<area coords="7" id="ex.criteria.param.3" />
</areaspec>
<programlisting>CriteriaQuery&lt;Person&gt; criteria = build.createQuery( Person.class );
<programlisting role="JAVA" language="JAVA">CriteriaQuery&lt;Person&gt; criteria = build.createQuery( Person.class );
Root&lt;Person&gt; personRoot = criteria.from( Person.class );
criteria.select( personRoot );
ParameterExpression&lt;String&gt; eyeColorParam = builder.parameter( String.class );

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,18 +22,22 @@
~ 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="queryhql">
<title>EJB-QL: The Object Query Language</title>
<title>JP-QL: The Object Query Language</title>
<para>
EJB3-QL has been heavily inspired by HQL, the native Hibernate Query Language. Both
are therefore very close to SQL, but portable and independent of the database schema.
People familiar with HQL shouldn't have any problem using EJB-QL. Actually, you
use the same query API for EJB-QL and HQL queries. Portable EJB3 applications however
should stick to EJB-QL or similar vendor extensions are needed.
</para>
<para>The Java Persistence Query Language (JP-QL) has been heavily inspired
by HQL, the native Hibernate Query Language. Both are therefore very close
to SQL, but portable and independent of the database schema. People familiar
with HQL shouldn't have any problem using JP-QL. In fact HQL is a strict
superset of JP-QL and you use the same query API for both types of queries.
Portable JPA applications however should stick to JP-QL.</para>
<note>
<para>For a type-safe approach to query, we highly recommend you to use
the Criteria query, see <xref linkend="querycriteria" />.</para>
</note>
<sect1 id="queryhql-casesensitivity">
<title>Case Sensitivity</title>
@ -45,7 +49,7 @@
<literal>org.hibernate.eg.Foo</literal> and <literal>foo.barSet</literal>
is not <literal>foo.BARSET</literal>.</para>
<para>This manual uses lowercase EJBQL keywords. Some users find queries
<para>This manual uses lowercase JP-QL keywords. Some users find queries
with uppercase keywords more readable, but we find this convention ugly
when embedded in Java code.</para>
</sect1>
@ -53,28 +57,28 @@
<sect1 id="queryhql-from">
<title>The from clause</title>
<para>The simplest possible EJB-QL query is of the form:</para>
<para>The simplest possible JP-QL query is of the form:</para>
<programlisting>select c from eg.Cat c</programlisting>
<para>which simply returns all instances of the class
<literal>eg.Cat</literal>. Unlike HQL, the select clause is not optional
in EJB-QL. We don't usually need to qualify the class name, since the
in JP-QL. We don't usually need to qualify the class name, since the
entity name defaults to the unqualified class name
(<literal>@Entity</literal>). So we almost always just write:</para>
<programlisting>select c from Cat c</programlisting>
<para>As you may have noticed you can assign aliases to classes, the
<literal>as</literal> keywork is optional. An alias allows you to refer
to <literal>Cat</literal> in other parts of the query.</para>
<literal>as</literal> keywork is optional. An alias allows you to refer to
<literal>Cat</literal> in other parts of the query.</para>
<programlisting>select cat from Cat as cat</programlisting>
<para>Multiple classes may appear, resulting in a cartesian product or
"cross" join.</para>
<programlisting>select form, param from Formula as form, Parameter as param</programlisting>
<programlisting>select from, param from Formula as form, Parameter as param</programlisting>
<para>It is considered good practice to name query aliases using an
initial lowercase, consistent with Java naming standards for local
@ -88,7 +92,7 @@
elements of a collection of values, using a
<literal>join</literal>.</para>
<programlisting>select cat, mate, kitten from Cat as cat
<programlisting>select cat, mate, kitten from Cat as cat
inner join cat.mate as mate
left outer join cat.kittens as kitten</programlisting>
@ -109,18 +113,18 @@
<para>The <literal>inner join</literal>, <literal>left outer
join</literal> constructs may be abbreviated.</para>
<programlisting>select cat, mate, kitten from Cat as cat
<programlisting>select cat, mate, kitten from Cat as cat
join cat.mate as mate
left join cat.kittens as kitten</programlisting>
<para>In addition, a "fetch" join allows associations or collections of
values to be initialized along with their parent objects, using a single
select. This is particularly useful in the case of a collection. It
effectively overrides the fetching options in the associations and collection
mapping metadata. See the Performance chapter of the Hibernate reference guide
for more information.</para>
effectively overrides the fetching options in the associations and
collection mapping metadata. See the Performance chapter of the Hibernate
reference guide for more information.</para>
<programlisting>select cat from Cat as cat
<programlisting>select cat from Cat as cat
inner join fetch cat.mate
left join fetch cat.kittens</programlisting>
@ -141,15 +145,12 @@
<literal>iterate()</literal>. Nor should <literal>fetch</literal> be used
together with <literal>setMaxResults()</literal> or
<literal>setFirstResult()</literal>. It is possible to create a cartesian
product by join fetching more than one collection in a query (as in the example
above), be careful the result of this product isn't bigger than you expect.
Join fetching multiple collection roles also sometimes gives unexpected results for
bag mappings, so be careful about how you formulate your queries in this case.</para>
<para>
TODO: The last statement is useless and typical developer thinking, please elaborate.
The word "sometimes" should never appear in any technical documentation.
</para>
product by join fetching more than one collection in a query (as in the
example above), be careful the result of this product isn't bigger than
you expect. Join fetching multiple collection roles gives unexpected
results for bag mappings as it is impossible for Hibernate to
differentiate legit duplicates of a given bag from artificial duplicates
created by the multi-table cartesian product.</para>
<para>If you are using property-level lazy fetching (with bytecode
instrumentation), it is possible to force Hibernate to fetch the lazy
@ -200,7 +201,8 @@ from DomesticCat as mother
inner join mother.mate as mate
left outer join mother.kittens as offspr</programlisting>
<para>or as an actual typesafe Java object,</para>
<para>or as an actual type-safe Java object (often called a view
object),</para>
<programlisting>select new Family(mother, mate, offspr)
from DomesticCat as mother
@ -254,7 +256,8 @@ from Cat cat</programlisting>
</itemizedlist>
<para>You may use arithmetic operators, concatenation, and recognized SQL
functions in the select clause (dpending on configured dialect, HQL specific feature):</para>
functions in the select clause (dpending on configured dialect, HQL
specific feature):</para>
<programlisting>select cat.weight + sum(kitten.weight)
from Cat cat
@ -281,7 +284,7 @@ select count(distinct cat.name), count(cat) from Cat cat</programlisting>
<para>returns instances not only of <literal>Cat</literal>, but also of
subclasses like <literal>DomesticCat</literal>. Hibernate queries may name
<emphasis>any</emphasis> Java class or interface in the
<literal>from</literal> clause (portable EJB-QL queries should only name
<literal>from</literal> clause (portable JP-QL queries should only name
mapped entities). The query will return instances of all persistent
classes that extend that class or implement the interface. The following
query would return all persistent objects:</para>
@ -342,7 +345,8 @@ where cat.mate = mate</programlisting>
<para>The special property (lowercase) <literal>id</literal> may be used
to reference the unique identifier of an object. (You may also use its
mapped identifer property name.). Note that this keyword is specific to HQL.</para>
mapped identifer property name.). Note that this keyword is specific to
HQL.</para>
<programlisting>select cat from Cat as cat where cat.id = 123
@ -426,15 +430,21 @@ where log.item.class = 'Payment' and log.item.id = payment.id</programlisting>
of</literal></para>
</listitem>
<listitem>
<para><literal>exists</literal>, <literal>all</literal>,
<literal>any</literal>, <literal>some</literal> (taking
subqueries)</para>
</listitem>
<listitem>
<para>"Simple" case, <literal>case ... when ... then ... else ...
end</literal>, and "searched" case, <literal>case when ... then ...
else ... end (specific to HQL)</literal></para>
else ... end</literal></para>
</listitem>
<listitem>
<para>string concatenation <literal>...||...</literal> or
<literal>concat(...,...) (use concat() for portable EJB-QL
<literal>concat(...,...) (use concat() for portable JP-QL
queries)</literal></para>
</listitem>
@ -452,9 +462,9 @@ where log.item.class = 'Payment' and log.item.id = payment.id</programlisting>
</listitem>
<listitem>
<para>Any function or operator defined by EJB-QL 3.0:
<literal>substring(), trim(), lower(), upper(), length(), locate(),
abs(), sqrt(), bit_length()</literal></para>
<para>Any function or operator: <literal>substring(), trim(), lower(),
upper(), length(), locate(), abs(), sqrt(),
bit_length()</literal></para>
</listitem>
<listitem>
@ -462,6 +472,13 @@ where log.item.class = 'Payment' and log.item.id = payment.id</programlisting>
<literal>nullif()</literal></para>
</listitem>
<listitem>
<para><literal>TYPE ... in ...</literal>, where the first argument is
an identifier variable and the second argument is the subclass to
restrict polymorphism to (or a list of subclasses surrounded by
parenthesis)</para>
</listitem>
<listitem>
<para><literal>cast(... as ...)</literal>, where the second argument
is the name of a Hibernate type, and <literal>extract(... from
@ -490,6 +507,11 @@ where log.item.class = 'Payment' and log.item.id = payment.id</programlisting>
<literal>'1970-01-01 10:00:01.0'</literal></para>
</listitem>
<listitem>
<para>JDBC escape syntax for dates (dependent on your JDBC driver
support) (eg. <code>where date = {d '2008-12-31'}</code>)</para>
</listitem>
<listitem>
<para>Java <literal>public static final</literal> constants
<literal>eg.Color.TABBY</literal></para>
@ -548,7 +570,7 @@ where log.item.class = 'Payment' and log.item.id = payment.id</programlisting>
supported when passed the element or index set of a collection
(<literal>elements</literal> and <literal>indices</literal> functions) or
the result of a subquery (see below). While subqueries are supported by
EJB-QL, <literal>elements</literal> and <literal>indices</literal> are
JP-QL, <literal>elements</literal> and <literal>indices</literal> are
specific HQL features.</para>
<programlisting>select mother from Cat as mother, Cat as kit
@ -567,7 +589,13 @@ where p.name = some elements(list.names)</programlisting>
<literal>elements</literal>, <literal>indices</literal>,
<literal>minindex</literal>, <literal>maxindex</literal>,
<literal>minelement</literal>, <literal>maxelement</literal> - may only be
used in the where clause in Hibernate3.</para>
used in the where clause in Hibernate.</para>
<para>JP-QL lets you access the key or the value of a map by using the
<literal>KEY()</literal> and <literal>VALUE()</literal> operations (even
access the Entry object using <literal>ENTRY()</literal>)</para>
<programlisting>SELECT i.name, VALUE(p) FROM Item i JOIN i.photos p WHERE KEY(p) LIKE %egret</programlisting>
<para>In HQL, elements of indexed collections (arrays, lists, maps) may be
referred to by index (in a where clause only):</para>
@ -687,7 +715,7 @@ order by count(kitten) asc, sum(kitten.weight) desc</programlisting>
<sect1 id="queryhql-subqueries">
<title>Subqueries</title>
<para>For databases that support subselects, EJB-QL supports subqueries
<para>For databases that support subselects, JP-QL supports subqueries
within queries. A subquery must be surrounded by parentheses (often by an
SQL aggregate function call). Even correlated subqueries (subqueries that
refer to an alias in the outer query) are allowed.</para>
@ -737,11 +765,11 @@ where not ( cat.name, cat.color ) in (
</sect1>
<sect1 id="queryhql-examples">
<title>EJB-QL examples</title>
<title>JP-QL examples</title>
<para>Hibernate queries can be quite powerful and complex. In fact, the
power of the query language is one of Hibernate's main selling points (and
now EJB-QL). Here are some example queries very similar to queries that I
now JP-QL). Here are some example queries very similar to queries that I
used on a recent project. Note that most queries you will write are much
simpler than these!</para>
@ -848,8 +876,8 @@ order by account.type.sortOrder, account.accountNumber, payment.dueDate</program
<sect1 id="queryhql-bulk">
<title>Bulk UPDATE &amp; DELETE Statements</title>
<para>Hibernate now supports UPDATE and DELETE statements in HQL/EJB-QL. See <xref
linkend="batch-direct" /> for details.</para>
<para>Hibernate now supports UPDATE and DELETE statements in HQL/JP-QL.
See <xref linkend="batch-direct" /> for details.</para>
</sect1>
<sect1 id="queryhql-tipstricks">
@ -888,4 +916,4 @@ from User as usr
group by usr.id, usr.name
having count(msg) = 0</programlisting>
</sect1>
</chapter>
</chapter>

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,8 +22,8 @@
~ 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="query_native">
<title>Native query</title>
@ -31,7 +31,7 @@
database. This is useful if you want to utilize database specific features
such as query hints or the CONNECT BY option in Oracle. It also provides a
clean migration path from a direct SQL/JDBC based application to Hibernate.
Note that Hibernate3 allows you to specify handwritten SQL (including stored
Note that Hibernate allows you to specify handwritten SQL (including stored
procedures) for all create, update, delete, and load operations (please
refer to the reference guide for more information.)</para>
@ -42,10 +42,10 @@
description will help the <literal>EntityManager</literal> to map your
columns onto entity properties. This is done using the
<literal>@SqlResultSetMapping</literal> annotation. Each
<literal>@SqlResultSetMapping </literal>has a name wich is used when
<literal>@SqlResultSetMapping </literal>has a name which is used when
creating a SQL query on <literal>EntityManager</literal>.</para>
<programlisting>@SqlResultSetMapping(name="GetNightAndArea", entities={
<programlisting role="JAVA" language="JAVA">@SqlResultSetMapping(name="GetNightAndArea", entities={
@EntityResult(name="org.hibernate.test.annotations.query.Night", fields = {
@FieldResult(name="id", column="nid"),
@FieldResult(name="duration", column="night_duration"),
@ -65,7 +65,7 @@
<para>You can also define scalar results and even mix entity results and
scalar results</para>
<programlisting>@SqlResultSetMapping(name="ScalarAndEntities",
<programlisting role="JAVA" language="JAVA">@SqlResultSetMapping(name="ScalarAndEntities",
entities={
@EntityResult(name="org.hibernate.test.annotations.query.Night", fields = {
@FieldResult(name="id", column="nid"),
@ -103,7 +103,7 @@
third one (not yet supported by Hibernate entity manager), returns pure
scalar results.</para>
<programlisting>String sqlQuery = "select night.id nid, night.night_duration, night.night_date, area.id aid, "
<programlisting role="JAVA" language="JAVA">String sqlQuery = "select night.id nid, night.night_duration, night.night_date, area.id aid, "
+ "night.area_id, area.name from Night night, Area area where night.area_id = area.id "
+ "and night.night_duration &gt;= ?";
Query q = entityManager.createNativeQuery(sqlQuery, "GetNightAndArea");
@ -113,7 +113,7 @@ q.getResultList();</programlisting>
<para>This native query returns nights and area based on the
<literal>GetNightAndArea</literal> result set.</para>
<programlisting>String sqlQuery = "select * from tbl_spaceship where owner = ?";
<programlisting role="JAVA" language="JAVA">String sqlQuery = "select * from tbl_spaceship where owner = ?";
Query q = entityManager.createNativeQuery(sqlQuery, SpaceShip.class);
q.setParameter( 1, "Han" );
q.getResultList();</programlisting>
@ -125,12 +125,12 @@ q.getResultList();</programlisting>
<sect1>
<title>Named queries</title>
<para>Native named queries share the same calling API than EJB-QL named
<para>Native named queries share the same calling API than JP-QL named
queries. Your code doesn't need to know the difference between the two.
This is very useful for migration from SQL to EJB-QL:</para>
This is very useful for migration from SQL to JP-QL:</para>
<programlisting>Query q = entityManager.createNamedQuery("getSeasonByNativeQuery");
<programlisting role="JAVA" language="JAVA">Query q = entityManager.createNamedQuery("getSeasonByNativeQuery");
q.setParameter( 1, name );
Season season = (Season) q.getSingleResult();</programlisting>
</sect1>
</chapter>
</chapter>

View File

@ -418,7 +418,7 @@
mechanism behind the scenes. The common entity manager and transaction
handling idiom looks like this:</para>
<programlisting>// Non-managed environment idiom
<programlisting role="JAVA" language="JAVA">// Non-managed environment idiom
EntityManager em = emf.createEntityManager();
EntityTransaction tx = null;
try {
@ -501,7 +501,7 @@ finally {
<para>If you use bean-managed transactions (BMT), the code will look
like this:</para>
<programlisting>// BMT idiom
<programlisting role="JAVA" language="JAVA">// BMT idiom
@Resource public UserTransaction utx;
@Resource public EntityManagerFactory factory;
@ -554,13 +554,13 @@ finally {
<para>Our entity manager/transaction management idiom for CMT and EJB3
container-use is reduced to this:</para>
<programlisting>//CMT idiom through injection
<programlisting role="JAVA" language="JAVA">//CMT idiom through injection
@PersistenceContext(name="sample") EntityManager em;</programlisting>
<para>Or this if you use Java Context and Dependency Injection
(CDI).</para>
<programlisting>@Inject EntityManager em;</programlisting>
<programlisting role="JAVA" language="JAVA">@Inject EntityManager em;</programlisting>
<para>In other words, all you have to do in a managed environment is to
inject the <literal>EntityManager</literal>, do your data access work,
@ -834,7 +834,7 @@ finally {
the least efficient in terms of database access. It is the approach most
similar to EJB2 entities:</para>
<programlisting>// foo is an instance loaded by a previous entity manager
<programlisting role="JAVA" language="JAVA">// foo is an instance loaded by a previous entity manager
em = factory.createEntityManager();
EntityTransaction t = em.getTransaction();
t.begin();
@ -895,7 +895,7 @@ em.close();</programlisting>
performance impact. The following examples show the idiom in a
non-managed environment:</para>
<programlisting>// foo is an instance loaded earlier by the extended entity manager
<programlisting role="JAVA" language="JAVA">// foo is an instance loaded earlier by the extended entity manager
em.getTransaction.begin(); // new connection to data store is obtained and tx started
foo.setProperty("bar");
em.getTransaction().commit(); // End tx, flush and check version, disconnect</programlisting>
@ -936,7 +936,7 @@ em.getTransaction().commit(); // End tx, flush and check version, disconnect</p
persistence context and then merges the changes using
<literal>EntityManager.merge()</literal>:</para>
<programlisting>// foo is an instance loaded by a non-extended entity manager
<programlisting role="JAVA" language="JAVA">// foo is an instance loaded by a non-extended entity manager
foo.setProperty("bar");
entityManager = factory.createEntityManager();
entityManager.getTransaction().begin();