HHH-4933 improve EM doc wrt JPA 2
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18941 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
9be297241d
commit
5aa0138ec2
|
@ -67,7 +67,7 @@
|
||||||
|
|
||||||
<para>If you use Maven, add the following dependencies</para>
|
<para>If you use Maven, add the following dependencies</para>
|
||||||
|
|
||||||
<programlisting><project ...>
|
<programlisting role="XML" language="XML"><project ...>
|
||||||
...
|
...
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
configuration, so by default, your persistence.xml will be quite
|
configuration, so by default, your persistence.xml will be quite
|
||||||
minimalist:</para>
|
minimalist:</para>
|
||||||
|
|
||||||
<programlisting><persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
<programlisting role="XML" language="XML"><persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||||
version="2.0">
|
version="2.0">
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
<para>Here's a more complete example of a
|
<para>Here's a more complete example of a
|
||||||
<filename><literal>persistence.xml</literal></filename> file</para>
|
<filename><literal>persistence.xml</literal></filename> file</para>
|
||||||
|
|
||||||
<programlisting><persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
<programlisting role="XML" language="XML"><persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||||
version="2.0">
|
version="2.0">
|
||||||
|
@ -211,7 +211,7 @@
|
||||||
environment, the persistence.xml file is not under the same root
|
environment, the persistence.xml file is not under the same root
|
||||||
directory or jar than your domain model).</para>
|
directory or jar than your domain model).</para>
|
||||||
|
|
||||||
<programlisting> <jar-file>file:/home/turin/work/local/lab8/build/classes</jar-file></programlisting>
|
<programlisting role="XML" language="XML"> <jar-file>file:/home/turin/work/local/lab8/build/classes</jar-file></programlisting>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para> See Hibernate Annotation's documentation for more
|
<para>See Hibernate Annotation's documentation for more
|
||||||
details.</para>
|
details.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -323,14 +323,14 @@
|
||||||
<literal><validation-mode></literal>. To use it, add a
|
<literal><validation-mode></literal>. To use it, add a
|
||||||
regular property</para>
|
regular property</para>
|
||||||
|
|
||||||
<programlisting><property name="javax.persistence.validation.mode">
|
<programlisting role="XML" language="XML"><property name="javax.persistence.validation.mode">
|
||||||
ddl
|
ddl
|
||||||
</property></programlisting>
|
</property></programlisting>
|
||||||
|
|
||||||
<para>With this approach, you can mix ddl and callback
|
<para>With this approach, you can mix ddl and callback
|
||||||
modes:</para>
|
modes:</para>
|
||||||
|
|
||||||
<programlisting><property name="javax.persistence.validation.mode">
|
<programlisting role="XML" language="XML"><property name="javax.persistence.validation.mode">
|
||||||
ddl, callback
|
ddl, callback
|
||||||
</property></programlisting>
|
</property></programlisting>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -427,7 +427,7 @@
|
||||||
the version embedded in the hibernate-entitymanager.jar. It won't fetch
|
the version embedded in the hibernate-entitymanager.jar. It won't fetch
|
||||||
the resource from the internet.</para>
|
the resource from the internet.</para>
|
||||||
|
|
||||||
<programlisting><persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
<programlisting role="XML" language="XML"><persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
|
||||||
version="2.0"></programlisting>
|
version="2.0"></programlisting>
|
||||||
|
@ -441,7 +441,7 @@
|
||||||
<classname>EntityManager</classname>. The bootstrap class is
|
<classname>EntityManager</classname>. The bootstrap class is
|
||||||
<classname>javax.persistence.Persistence</classname>, e.g.</para>
|
<classname>javax.persistence.Persistence</classname>, e.g.</para>
|
||||||
|
|
||||||
<programlisting>EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
|
<programlisting role="JAVA" language="JAVA">EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
|
||||||
|
|
||||||
//or
|
//or
|
||||||
|
|
||||||
|
@ -528,8 +528,6 @@ EntityManagerFactory programmaticEmf =
|
||||||
reference documentation for a complete listing. There are however a
|
reference documentation for a complete listing. There are however a
|
||||||
couple of properties available in the EJB3 provider only.</para>
|
couple of properties available in the EJB3 provider only.</para>
|
||||||
|
|
||||||
<para></para>
|
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<title>Hibernate Entity Manager specific properties</title>
|
<title>Hibernate Entity Manager specific properties</title>
|
||||||
|
|
||||||
|
@ -665,7 +663,7 @@ EntityManagerFactory programmaticEmf =
|
||||||
|
|
||||||
<para>Here is a typical configuration in a Java SE environment</para>
|
<para>Here is a typical configuration in a Java SE environment</para>
|
||||||
|
|
||||||
<programlisting><persistence>
|
<programlisting role="XML" language="XML"><persistence>
|
||||||
<persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL">
|
<persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL">
|
||||||
<class>org.hibernate.ejb.test.Cat</class>
|
<class>org.hibernate.ejb.test.Cat</class>
|
||||||
<class>org.hibernate.ejb.test.Distributor</class>
|
<class>org.hibernate.ejb.test.Distributor</class>
|
||||||
|
@ -697,7 +695,7 @@ EntityManagerFactory programmaticEmf =
|
||||||
|
|
||||||
<para>TODO: me more descriptive on some APIs like setDatasource()</para>
|
<para>TODO: me more descriptive on some APIs like setDatasource()</para>
|
||||||
|
|
||||||
<programlisting>Ejb3Configuration cfg = new Ejb3Configuration();
|
<programlisting role="JAVA" language="JAVA">Ejb3Configuration cfg = new Ejb3Configuration();
|
||||||
EntityManagerFactory emf =
|
EntityManagerFactory emf =
|
||||||
cfg.addProperties( properties ) //add some properties
|
cfg.addProperties( properties ) //add some properties
|
||||||
.setInterceptor( myInterceptorImpl ) // set an interceptor
|
.setInterceptor( myInterceptorImpl ) // set an interceptor
|
||||||
|
@ -714,9 +712,9 @@ EntityManagerFactory emf =
|
||||||
<title>Event listeners</title>
|
<title>Event listeners</title>
|
||||||
|
|
||||||
<para>Hibernate Entity Manager needs to enhance Hibernate core to
|
<para>Hibernate Entity Manager needs to enhance Hibernate core to
|
||||||
implements all the EJB3 semantics. It does that through the event listener
|
implements all the JPA semantics. It does that through the event listener
|
||||||
system of Hibernate. Be careful when you use the event system yourself,
|
system of Hibernate. Be careful when you use the event system yourself,
|
||||||
you might override some of the EJB3 semantics. A safe way is to add your
|
you might override some of the JPA semantics. A safe way is to add your
|
||||||
event listeners to the list given below.</para>
|
event listeners to the list given below.</para>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
|
@ -793,15 +791,13 @@ EntityManagerFactory emf =
|
||||||
<row>
|
<row>
|
||||||
<entry>pre-insert</entry>
|
<entry>pre-insert</entry>
|
||||||
|
|
||||||
<entry>org.hibernate.secure.JACCPreInsertEventListener,
|
<entry>org.hibernate.secure.JACCPreInsertEventListener</entry>
|
||||||
org.hibernate.valitator.event.ValidateEventListener</entry>
|
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry>pre-insert</entry>
|
<entry>pre-insert</entry>
|
||||||
|
|
||||||
<entry>org.hibernate.secure.JACCPreUpdateEventListener,
|
<entry>org.hibernate.secure.JACCPreUpdateEventListener</entry>
|
||||||
org.hibernate.valitator.event.ValidateEventListener</entry>
|
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
|
@ -861,7 +857,7 @@ EntityManagerFactory emf =
|
||||||
<classname>Persistence</classname> class is bootstrap class to create an
|
<classname>Persistence</classname> class is bootstrap class to create an
|
||||||
entity manager factory.</para>
|
entity manager factory.</para>
|
||||||
|
|
||||||
<programlisting>// Use persistence.xml configuration
|
<programlisting role="JAVA" language="JAVA">// Use persistence.xml configuration
|
||||||
EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1")
|
EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1")
|
||||||
EntityManager em = emf.createEntityManager(); // Retrieve an application managed entity manager
|
EntityManager em = emf.createEntityManager(); // Retrieve an application managed entity manager
|
||||||
// Work with the EM
|
// Work with the EM
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version='1.0' encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!--
|
||||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
~
|
~
|
||||||
|
@ -22,15 +22,15 @@
|
||||||
~ 51 Franklin Street, Fifth Floor
|
~ 51 Franklin Street, Fifth Floor
|
||||||
~ Boston, MA 02110-1301 USA
|
~ Boston, MA 02110-1301 USA
|
||||||
-->
|
-->
|
||||||
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||||
<chapter id="objectstate">
|
<chapter id="objectstate">
|
||||||
<title>Working with objects</title>
|
<title>Working with objects</title>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Entity states</title>
|
<title>Entity states</title>
|
||||||
|
|
||||||
<para>Like in Hibernate (comparable terms in parantheses), an entity
|
<para>Like in Hibernate (comparable terms in parentheses), an entity
|
||||||
instance is in one of the following states:</para>
|
instance is in one of the following states:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
|
|
||||||
<para>The <classname>EntityManager</classname> API allows you to change
|
<para>The <classname>EntityManager</classname> API allows you to change
|
||||||
the state of an entity, or in other words, to load and store objects. You
|
the state of an entity, or in other words, to load and store objects. You
|
||||||
will find persistence with EJB3 easier to understand if you think about
|
will find persistence with JPA easier to understand if you think about
|
||||||
object state management, not managing of SQL statements.</para>
|
object state management, not managing of SQL statements.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -102,7 +102,8 @@ em.find( Cat.class, new Long(catId) );</programlisting>
|
||||||
<para>In some cases, you don't really want to load the object state, but
|
<para>In some cases, you don't really want to load the object state, but
|
||||||
just having a reference to it (ie a proxy). You can get this reference
|
just having a reference to it (ie a proxy). You can get this reference
|
||||||
using the <literal>getReference()</literal> method. This is especially
|
using the <literal>getReference()</literal> method. This is especially
|
||||||
useful to link a child to its parent without having to load the parent.</para>
|
useful to link a child to its parent without having to load the
|
||||||
|
parent.</para>
|
||||||
|
|
||||||
<programlisting>child = new Child();
|
<programlisting>child = new Child();
|
||||||
child.SetName("Henry");
|
child.SetName("Henry");
|
||||||
|
@ -128,32 +129,33 @@ em.refresh(cat); //re-read the state (after the trigger executes)</programlistin
|
||||||
<para>If you don't know the identifier values of the objects you are
|
<para>If you don't know the identifier values of the objects you are
|
||||||
looking for, you need a query. The Hibernate EntityManager implementation
|
looking for, you need a query. The Hibernate EntityManager implementation
|
||||||
supports an easy-to-use but powerful object-oriented query language
|
supports an easy-to-use but powerful object-oriented query language
|
||||||
(EJB3-QL) which has been inspired by HQL (and vice-versa). Both query
|
(JP-QL) which has been inspired by HQL (and vice-versa). HQL is strictly
|
||||||
languages are portable across databases, the use entity and property names
|
speaking a superset of JP-QL. Both query languages are portable across
|
||||||
as identifiers (instead of table and column names). You may also express
|
databases, the use entity and property names as identifiers (instead of
|
||||||
your query in the native SQL of your database, with optional support from
|
table and column names). You may also express your query in the native SQL
|
||||||
EJB3 for result set conversion into Java business objects.</para>
|
of your database, with optional support from JPA for result set conversion
|
||||||
|
into Java business objects.</para>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Executing queries</title>
|
<title>Executing queries</title>
|
||||||
|
|
||||||
<para>EJB3QL and SQL queries are represented by an instance of
|
<para>JP-QL and SQL queries are represented by an instance of
|
||||||
<classname>javax.persistence.Query</classname>. This interface offers
|
<classname>javax.persistence.Query</classname>. This interface offers
|
||||||
methods for parameter binding, result set handling, and for execution of
|
methods for parameter binding, result set handling, and for execution of
|
||||||
the query. Queries are always created using the current entity
|
the query. Queries are always created using the current entity
|
||||||
manager:</para>
|
manager:</para>
|
||||||
|
|
||||||
<programlisting>List cats = em.createQuery(
|
<programlisting>List<?> cats = em.createQuery(
|
||||||
"select cat from Cat as cat where cat.birthdate < ?1")
|
"select cat from Cat as cat where cat.birthdate < ?1")
|
||||||
.setParameter(1, date, TemporalType.DATE)
|
.setParameter(1, date, TemporalType.DATE)
|
||||||
.getResultList();
|
.getResultList();
|
||||||
|
|
||||||
List mothers = em.createQuery(
|
List<?> mothers = em.createQuery(
|
||||||
"select mother from Cat as cat join cat.mother as mother where cat.name = ?1")
|
"select mother from Cat as cat join cat.mother as mother where cat.name = ?1")
|
||||||
.setParameter(1, name)
|
.setParameter(1, name)
|
||||||
.getResultList();
|
.getResultList();
|
||||||
|
|
||||||
List kittens = em.createQuery(
|
List<?> kittens = em.createQuery(
|
||||||
"from Cat as cat where cat.mother = ?1")
|
"from Cat as cat where cat.mother = ?1")
|
||||||
.setEntity(1, pk)
|
.setEntity(1, pk)
|
||||||
.getResultList();
|
.getResultList();
|
||||||
|
@ -165,17 +167,43 @@ Cat mother = (Cat) em.createQuery(
|
||||||
|
|
||||||
<para>A query is usually executed by invoking
|
<para>A query is usually executed by invoking
|
||||||
<methodname>getResultList()</methodname>. This method loads the
|
<methodname>getResultList()</methodname>. This method loads the
|
||||||
resulting instances of the query completly into memory. Entity instances
|
resulting instances of the query completely into memory. Entity
|
||||||
retrieved by a query are in persistent state. The
|
instances retrieved by a query are in persistent state. The
|
||||||
<methodname>getSingleResult() </methodname>method offers a shortcut if
|
<methodname>getSingleResult() </methodname>method offers a shortcut if
|
||||||
you know your query will only return a single object.</para>
|
you know your query will only return a single object.</para>
|
||||||
|
|
||||||
|
<para>JPA 2 provides more type-safe approaches to queries. The truly
|
||||||
|
type-safe approach is the Criteria API explained in <xref
|
||||||
|
linkend="querycriteria" />.</para>
|
||||||
|
|
||||||
|
<programlisting>CriteriaQuery<Cat> criteria = builder.createQuery( Cat.class );
|
||||||
|
Root<Cat> cat = criteria.from( Cat.class );
|
||||||
|
criteria.select( cat );
|
||||||
|
criteria.where( builder.lt( cat.get( Cat_.birthdate ), catDate ) );
|
||||||
|
List<Cat> cats = em.createQuery( criteria ).getResultList(); //notice no downcasting is necessary</programlisting>
|
||||||
|
|
||||||
|
<para>But you can benefit form some type-safe convenience even when
|
||||||
|
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
|
||||||
|
List<Cat> cats = em.createQuery(
|
||||||
|
"select cat from Cat as cat where cat.birthdate < ?1", Cat.class)
|
||||||
|
.setParameter(1, date, TemporalType.DATE)
|
||||||
|
.getResultList();</programlisting>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>We highly recommend the Criteria API approach. While more
|
||||||
|
verbose, it provides compiler-enforced safety (including down to
|
||||||
|
property names) which will pay off when the application will move to
|
||||||
|
maintenance mode.</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Projection</title>
|
<title>Projection</title>
|
||||||
|
|
||||||
<para>An EJB3QL query queries can return tuples of objects if
|
<para>JPA queries can return tuples of objects if projection is used.
|
||||||
projection is used. Each result tuple is returned as an object
|
Each result tuple is returned as an object array:</para>
|
||||||
array:</para>
|
|
||||||
|
|
||||||
<programlisting>Iterator kittensAndMothers = sess.createQuery(
|
<programlisting>Iterator kittensAndMothers = sess.createQuery(
|
||||||
"select kitten, mother from Cat kitten join kitten.mother mother")
|
"select kitten, mother from Cat kitten join kitten.mother mother")
|
||||||
|
@ -188,6 +216,11 @@ while ( kittensAndMothers.hasNext() ) {
|
||||||
Cat mother = (Cat) tuple[1];
|
Cat mother = (Cat) tuple[1];
|
||||||
....
|
....
|
||||||
}</programlisting>
|
}</programlisting>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>The criteria API provides a type-safe approach to projection
|
||||||
|
results. Check out <xref linkend="querycriteria-tuple" />.</para>
|
||||||
|
</note>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
@ -220,9 +253,9 @@ while ( results.hasNext() ) {
|
||||||
|
|
||||||
<para>Both named and positional query parameters are supported, the
|
<para>Both named and positional query parameters are supported, the
|
||||||
<literal>Query</literal> API offers several methods to bind arguments.
|
<literal>Query</literal> API offers several methods to bind arguments.
|
||||||
The EJB3 specification numbers positional parameters from one. Named
|
The JPA specification numbers positional parameters from one. Named
|
||||||
parameters are identifiers of the form <literal>:paramname</literal>
|
parameters are identifiers of the form <literal>:paramname</literal>
|
||||||
in the query string. Named parameters should be prefered, they are
|
in the query string. Named parameters should be preferred, they are
|
||||||
more robust and easier to read and understand:</para>
|
more robust and easier to read and understand:</para>
|
||||||
|
|
||||||
<programlisting>// Named parameter (preferred)
|
<programlisting>// Named parameter (preferred)
|
||||||
|
@ -268,13 +301,20 @@ List cats = q.getResultList(); //return cats from the 20th position to 29th</pro
|
||||||
<programlisting>@javax.persistence.NamedQuery(name="eg.DomesticCat.by.name.and.minimum.weight",
|
<programlisting>@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 > ?2")</programlisting>
|
query="select cat from eg.DomesticCat as cat where cat.name = ?1 and cat.weight > ?2")</programlisting>
|
||||||
|
|
||||||
<para>Parameters are bound programatically to the named query, before
|
<para>Parameters are bound programmatically to the named query, before
|
||||||
it is executed:</para>
|
it is executed:</para>
|
||||||
|
|
||||||
<programlisting>Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight");
|
<programlisting>Query q = em.createNamedQuery("eg.DomesticCat.by.name.and.minimum.weight");
|
||||||
q.setString(1, name);
|
q.setString(1, name);
|
||||||
q.setInt(2, minWeight);
|
q.setInt(2, minWeight);
|
||||||
List cats = q.getResultList();</programlisting>
|
List<?> 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);
|
||||||
|
q.setString(1, name);
|
||||||
|
q.setInt(2, minWeight);
|
||||||
|
List<Cat> cats = q.getResultList();</programlisting>
|
||||||
|
|
||||||
<para>Note that the actual program code is independent of the query
|
<para>Note that the actual program code is independent of the query
|
||||||
language that is used, you may also define native SQL queries in
|
language that is used, you may also define native SQL queries in
|
||||||
|
@ -314,6 +354,29 @@ item = (Item) q.getSingleResult(); //from a class columns names match the mappin
|
||||||
</note>
|
</note>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<para>Adjusting the flush mode is interesting when one must guaranty
|
||||||
|
that a query execution will not trigger a flush operation. Most of the
|
||||||
|
time you don't need to care about this.</para>
|
||||||
|
|
||||||
|
<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)
|
||||||
|
.setLockMode(LockModeType.PESSIMISTIC_READ);</programlisting>
|
||||||
|
|
||||||
|
<note>
|
||||||
|
<para>If you want to use <literal>FlushMode.MANUAL</literal> (ie the
|
||||||
|
Hibernate specific flush mode), you will need to use a query hint.
|
||||||
|
See below.</para>
|
||||||
|
</note>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Query hints</title>
|
<title>Query hints</title>
|
||||||
|
|
||||||
|
@ -395,7 +458,9 @@ item = (Item) q.getSingleResult(); //from a class columns names match the mappin
|
||||||
<row>
|
<row>
|
||||||
<entry>org.hibernate.flushMode</entry>
|
<entry>org.hibernate.flushMode</entry>
|
||||||
|
|
||||||
<entry>Flush mode used for this query</entry>
|
<entry>Flush mode used for this query (useful to pass
|
||||||
|
Hibernate specific flush modes, in particular
|
||||||
|
<literal>MANUAL</literal>).</entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
<row>
|
<row>
|
||||||
|
@ -437,6 +502,20 @@ em.flush(); // changes to cat are automatically detected and persisted</program
|
||||||
an alternate approach, using detached instances.</para>
|
an alternate approach, using detached instances.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Detaching a object</title>
|
||||||
|
|
||||||
|
<para>An object when loaded in the persistence context is managed by
|
||||||
|
Hibernate. You can force an object to be detached (ie. no longer managed
|
||||||
|
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) );
|
||||||
|
...
|
||||||
|
em.detach(cat);
|
||||||
|
cat.setName("New name"); //not propatated to the database</programlisting>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>Modifying detached objects</title>
|
<title>Modifying detached objects</title>
|
||||||
|
|
||||||
|
@ -447,7 +526,7 @@ em.flush(); // changes to cat are automatically detected and persisted</program
|
||||||
approach in a high-concurrency environment usually use versioned data to
|
approach in a high-concurrency environment usually use versioned data to
|
||||||
ensure isolation for the "long" unit of work.</para>
|
ensure isolation for the "long" unit of work.</para>
|
||||||
|
|
||||||
<para>The EJB3 specifications supports this development model by providing
|
<para>The JPA specifications supports this development model by providing
|
||||||
for persistence of modifications made to detached instances using the
|
for persistence of modifications made to detached instances using the
|
||||||
<methodname>EntityManager.merge()</methodname> method:</para>
|
<methodname>EntityManager.merge()</methodname> method:</para>
|
||||||
|
|
||||||
|
@ -559,7 +638,7 @@ secondEntityManager.merge(mate); // save the new instance</programlisting>
|
||||||
<note>
|
<note>
|
||||||
<title>Merging vs. saveOrUpdate/saveOrUpdateCopy</title>
|
<title>Merging vs. saveOrUpdate/saveOrUpdateCopy</title>
|
||||||
|
|
||||||
<para>Merging in EJB3 is similar to the
|
<para>Merging in JPA is similar to the
|
||||||
<literal>saveOrUpdateCopy()</literal> method in native Hibernate.
|
<literal>saveOrUpdateCopy()</literal> method in native Hibernate.
|
||||||
However, it is not the same as the <literal>saveOrUpdate()</literal>
|
However, it is not the same as the <literal>saveOrUpdate()</literal>
|
||||||
method, the given instance is not reattached with the persistence
|
method, the given instance is not reattached with the persistence
|
||||||
|
@ -582,14 +661,15 @@ secondEntityManager.merge(mate); // save the new instance</programlisting>
|
||||||
<section>
|
<section>
|
||||||
<title>Flush the persistence context</title>
|
<title>Flush the persistence context</title>
|
||||||
|
|
||||||
|
<para>From time to time the entity manager will execute the SQL DML
|
||||||
|
statements needed to synchronize the data store with the state of objects
|
||||||
|
held in memory. This process is called flushing.</para>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>In a transaction</title>
|
<title>In a transaction</title>
|
||||||
|
|
||||||
<para>From time to time the entity manager will execute the SQL DML
|
<para>Flush occurs by default (this is Hibernate specific and not
|
||||||
statements needed to synchronize the data store with the state of
|
defined by the specification) at the following points:</para>
|
||||||
objects held in memory. This process, flush, occurs by default (this is
|
|
||||||
Hibernate specific and not defined by the specification) at the
|
|
||||||
following points:</para>
|
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -645,10 +725,10 @@ secondEntityManager.merge(mate); // save the new instance</programlisting>
|
||||||
<para>(Exception: entity instances using application-assigned
|
<para>(Exception: entity instances using application-assigned
|
||||||
identifiers are inserted when they are saved.)</para>
|
identifiers are inserted when they are saved.)</para>
|
||||||
|
|
||||||
<para>Except when you explicity <methodname>flush()</methodname>, there
|
<para>Except when you explicitly <methodname>flush()</methodname>, there
|
||||||
are absolutely no guarantees about when the entity manager executes the
|
are no guarantees about when the entity manager executes the JDBC calls,
|
||||||
JDBC calls, only the order in which they are executed. However,
|
only the order in which they are executed. However, Hibernate does
|
||||||
Hibernate does guarantee that the
|
guarantee that the
|
||||||
<methodname>Query.getResultList()</methodname>/<methodname>Query.getSingleResult()</methodname>
|
<methodname>Query.getResultList()</methodname>/<methodname>Query.getSingleResult()</methodname>
|
||||||
will never return stale data; nor will they return wrong data if
|
will never return stale data; nor will they return wrong data if
|
||||||
executed in an active transaction.</para>
|
executed in an active transaction.</para>
|
||||||
|
@ -677,7 +757,8 @@ em.getTransaction().commit(); // flush occurs</programlisting>
|
||||||
violates a constraint). TODO: Add link to exception handling.</para>
|
violates a constraint). TODO: Add link to exception handling.</para>
|
||||||
|
|
||||||
<para>Hibernate provides more flush modes than the one described in the
|
<para>Hibernate provides more flush modes than the one described in the
|
||||||
EJB3 specification. Please refer to the Hibernate core reference
|
JPA specification. In particular <literal>FlushMode.MANUAL</literal> for
|
||||||
|
long running conversation. Please refer to the Hibernate core reference
|
||||||
documentation for more informations.</para>
|
documentation for more informations.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -730,9 +811,11 @@ em.getTransaction().commit(); // flush occurs</programlisting>
|
||||||
<methodname>persist()</methodname>, <methodname>merge()</methodname>,
|
<methodname>persist()</methodname>, <methodname>merge()</methodname>,
|
||||||
<methodname>remove()</methodname>, <methodname>refresh()</methodname> -
|
<methodname>remove()</methodname>, <methodname>refresh()</methodname> -
|
||||||
there is a corresponding cascade style. Respectively, the cascade styles
|
there is a corresponding cascade style. Respectively, the cascade styles
|
||||||
are named PERSIST, MERGE, REMOVE, REFRESH. If you want an operation to be
|
are named <literal>PERSIST</literal>, <literal>MERGE</literal>,
|
||||||
cascaded to associated entity (or collection of entities), you must
|
<literal>REMOVE</literal>, <literal>REFRESH</literal>,
|
||||||
indicate that in the association annotation:</para>
|
<literal>DETACH</literal>. If you want an operation to be cascaded to
|
||||||
|
associated entity (or collection of entities), you must indicate that in
|
||||||
|
the association annotation:</para>
|
||||||
|
|
||||||
<programlisting>@OneToOne(cascade=CascadeType.PERSIST)</programlisting>
|
<programlisting>@OneToOne(cascade=CascadeType.PERSIST)</programlisting>
|
||||||
|
|
||||||
|
@ -740,9 +823,16 @@ em.getTransaction().commit(); // flush occurs</programlisting>
|
||||||
|
|
||||||
<programlisting>@OneToOne(cascade= { CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH } )</programlisting>
|
<programlisting>@OneToOne(cascade= { CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.REFRESH } )</programlisting>
|
||||||
|
|
||||||
<para>You may even use CascadeType.ALL to specify that all operations
|
<para>You may even use <literal>CascadeType.ALL</literal> to specify that
|
||||||
should be cascaded for a particular association. Remember that by default,
|
all operations should be cascaded for a particular association. Remember
|
||||||
no operation is cascaded.</para>
|
that by default, no operation is cascaded.</para>
|
||||||
|
|
||||||
|
<para>There is an additional cascading mode used to describe orphan
|
||||||
|
deletion (ie an object no longer linked to an owning object should be
|
||||||
|
removed automatically by Hibernate. Use
|
||||||
|
<literal>orphanRemoval=true</literal> on <classname>@OneToOne</classname>
|
||||||
|
or <classname>@OneToMany</classname>. Check Hibernate Annotations's
|
||||||
|
documentation for more information.</para>
|
||||||
|
|
||||||
<para>Hibernate offers more native cascading options, please refer to the
|
<para>Hibernate offers more native cascading options, please refer to the
|
||||||
Hibernate Annotations manual and the Hibernate reference guide for more
|
Hibernate Annotations manual and the Hibernate reference guide for more
|
||||||
|
@ -780,25 +870,58 @@ em.getTransaction().commit(); // flush occurs</programlisting>
|
||||||
<section>
|
<section>
|
||||||
<title>Locking</title>
|
<title>Locking</title>
|
||||||
|
|
||||||
<para>The default locking system in EJB3 is mostly based on optimistic
|
<para>You can define various levels of locking strategies. A lock can be
|
||||||
locking (ie using a version column to check any concurrency issues). EJB3
|
applied in several ways:</para>
|
||||||
has defined an additional mechanism to increase the concurrency
|
|
||||||
guaranties. You can apply a lock on a given entity (and it's associated
|
|
||||||
entities if <literal>LOCK</literal> is cascaded) through the
|
|
||||||
<methodname>lock(Object entity)</methodname> method. Depending on the
|
|
||||||
concurrency guaranties you requires, you choose a lock mode:</para>
|
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para><literal>LockMode.READ</literal> prevents dirty-reads and non
|
<para>via the explicit <methodname>entityManager.lock()</methodname>
|
||||||
repeatable read on a given entity.</para>
|
method</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para><literal>LockMode.WRITE</literal> prevents dirty-reads and non
|
<para>via lookup methods on <classname>EntityManager</classname>:
|
||||||
repeatable read on a given entity and force an increase of the version
|
<literal>find()</literal>, <literal>refresh()</literal></para>
|
||||||
number if any.</para>
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>on queries: <methodname>query.setLockMode()</methodname></para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>You can use various lock approaches:</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para><literal>OPTIMISTIC</literal> (previously
|
||||||
|
<literal>READ</literal>): use an optimistic locking scheme where the
|
||||||
|
version number is compared: the version number is compared and has to
|
||||||
|
match before the transaction is committed.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><literal>OPTIMISTIC_FORCE_INCREMENT</literal> (previously
|
||||||
|
<literal>WRITE</literal>): use an optimistic locking scheme but force
|
||||||
|
a version number increase as well: the version number is compared and
|
||||||
|
has to match before the transaction is committed.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><literal>PESSIMISTIC_READ</literal>: apply a database-level read
|
||||||
|
lock when the lock operation is requested: roughly concurrent readers
|
||||||
|
are allowed but no writer is allowed.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><literal>PESSIMISTIC_WRITE</literal>: apply a database-level
|
||||||
|
write lock when the lock operation is requested: roughly no reader nor
|
||||||
|
writer is allowed.</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>All these locks prevent dirty reads and non-repeatable reads on a
|
||||||
|
given entity. Optimistic locks enforce the lock as late as possible hoping
|
||||||
|
nobody changes the data underneath while pessimistic locks enforce the
|
||||||
|
lock right away and keep it till the transaction is committed.</para>
|
||||||
</section>
|
</section>
|
||||||
</chapter>
|
</chapter>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
<?xml version='1.0' encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!--
|
||||||
~ Hibernate, Relational Persistence for Idiomatic Java
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
~
|
~
|
||||||
|
@ -22,8 +22,8 @@
|
||||||
~ 51 Franklin Street, Fifth Floor
|
~ 51 Franklin Street, Fifth Floor
|
||||||
~ Boston, MA 02110-1301 USA
|
~ Boston, MA 02110-1301 USA
|
||||||
-->
|
-->
|
||||||
|
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||||
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||||
<chapter id="transactions" revision="1">
|
<chapter id="transactions" revision="1">
|
||||||
<title>Transactions and Concurrency</title>
|
<title>Transactions and Concurrency</title>
|
||||||
|
|
||||||
|
@ -95,23 +95,22 @@
|
||||||
|
|
||||||
<para>The most common pattern in a multi-user client/server application
|
<para>The most common pattern in a multi-user client/server application
|
||||||
is <emphasis>entitymanager-per-request</emphasis>. In this model, a
|
is <emphasis>entitymanager-per-request</emphasis>. In this model, a
|
||||||
request from the client is send to the server (where the EJB3
|
request from the client is send to the server (where the JPA persistence
|
||||||
persistence layer runs), a new <literal>EntityManager</literal> is
|
layer runs), a new <literal>EntityManager</literal> is opened, and all
|
||||||
opened, and all database operations are executed in this unit of work.
|
database operations are executed in this unit of work. Once the work has
|
||||||
Once the work has been completed (and the response for the client has
|
been completed (and the response for the client has been prepared), the
|
||||||
been prepared), the persistence context is flushed and closed, as well
|
persistence context is flushed and closed, as well as the entity manager
|
||||||
as the entity manager object. You would also use a single database
|
object. You would also use a single database transaction to serve the
|
||||||
transaction to serve the clients request. The relationship between the
|
clients request. The relationship between the two is one-to-one and this
|
||||||
two is one-to-one and this model is a perfect fit for many
|
model is a perfect fit for many applications.</para>
|
||||||
applications.</para>
|
|
||||||
|
|
||||||
<para>This is the default EJB3 persistence model in a Java EE
|
<para>This is the default JPA persistence model in a Java EE environment
|
||||||
environment (JTA bounded, transaction-scoped persistence context);
|
(JTA bounded, transaction-scoped persistence context); injected (or
|
||||||
injected (or looked up) entity managers share the same persistence
|
looked up) entity managers share the same persistence context for a
|
||||||
context for a particular JTA transaction. The beauty of EJB3 is that you
|
particular JTA transaction. The beauty of JPA is that you don't have to
|
||||||
don't have to care about that anymore and just see data access through
|
care about that anymore and just see data access through entity manager
|
||||||
entity manager and demarcation of transaction scope on session beans as
|
and demarcation of transaction scope on session beans as completely
|
||||||
completely orthogonal.</para>
|
orthogonal.</para>
|
||||||
|
|
||||||
<para>The challenge is the implementation of this (and other) behavior
|
<para>The challenge is the implementation of this (and other) behavior
|
||||||
outside an EJB3 container: not only has the
|
outside an EJB3 container: not only has the
|
||||||
|
@ -187,14 +186,14 @@
|
||||||
transactions (the last one) stores the updated data, all others simply
|
transactions (the last one) stores the updated data, all others simply
|
||||||
read data (e.g. in a wizard-style dialog spanning several
|
read data (e.g. in a wizard-style dialog spanning several
|
||||||
request/response cycles). This is easier to implement than it might
|
request/response cycles). This is easier to implement than it might
|
||||||
sound, especially if you use EJB3 entity manager and persistence context
|
sound, especially if you use JPA entity manager and persistence context
|
||||||
features:</para>
|
features:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para><emphasis>Automatic Versioning</emphasis> - An entity manager
|
<para><emphasis>Automatic Versioning</emphasis> - An entity manager
|
||||||
can do automatic optimistic concurrency control for you, it can
|
can do automatic optimistic concurrency control for you, it can
|
||||||
automatically detect if a concurrent modification occured during
|
automatically detect if a concurrent modification occurred during
|
||||||
user think time (usually by comparing version numbers or timestamps
|
user think time (usually by comparing version numbers or timestamps
|
||||||
when updating the data in the final resource-local
|
when updating the data in the final resource-local
|
||||||
transaction).</para>
|
transaction).</para>
|
||||||
|
@ -249,9 +248,7 @@
|
||||||
<term>Database Identity</term>
|
<term>Database Identity</term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para><literal>foo.getId().equals( bar.getId() )</literal></para>
|
||||||
<literal>foo.getId().equals( bar.getId() )</literal>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -259,9 +256,7 @@
|
||||||
<term>JVM Identity</term>
|
<term>JVM Identity</term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para><literal>foo==bar</literal></para>
|
||||||
<literal>foo==bar</literal>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
@ -371,8 +366,8 @@
|
||||||
<sect1 id="transactions-demarcation">
|
<sect1 id="transactions-demarcation">
|
||||||
<title>Database transaction demarcation</title>
|
<title>Database transaction demarcation</title>
|
||||||
|
|
||||||
<para>Database (or system) transaction boundaries are always necessary.
|
<para>Database (or system) transaction boundaries are always necessary. No
|
||||||
No communication with the database can occur outside of a database
|
communication with the database can occur outside of a database
|
||||||
transaction (this seems to confuse many developers who are used to the
|
transaction (this seems to confuse many developers who are used to the
|
||||||
auto-commit mode). Always use clear transaction boundaries, even for
|
auto-commit mode). Always use clear transaction boundaries, even for
|
||||||
read-only operations. Depending on your isolation level and database
|
read-only operations. Depending on your isolation level and database
|
||||||
|
@ -381,8 +376,8 @@
|
||||||
outside a transaction, though, when you'll need to retain modifications in
|
outside a transaction, though, when you'll need to retain modifications in
|
||||||
an <literal>EXTENDED</literal> persistence context.</para>
|
an <literal>EXTENDED</literal> persistence context.</para>
|
||||||
|
|
||||||
<para>An EJB3 application can run in non-managed (i.e. standalone, simple
|
<para>A JPA application can run in non-managed (i.e. standalone, simple
|
||||||
Web- or Swing applications) and managed J2EE environments. In a
|
Web- or Swing applications) and managed Java EE environments. In a
|
||||||
non-managed environment, an <literal>EntityManagerFactory</literal> is
|
non-managed environment, an <literal>EntityManagerFactory</literal> is
|
||||||
usually responsible for its own database connection pool. The application
|
usually responsible for its own database connection pool. The application
|
||||||
developer has to manually set transaction boundaries, in other words,
|
developer has to manually set transaction boundaries, in other words,
|
||||||
|
@ -418,7 +413,7 @@
|
||||||
<sect2 id="transactions-demarcation-nonmanaged">
|
<sect2 id="transactions-demarcation-nonmanaged">
|
||||||
<title>Non-managed environment</title>
|
<title>Non-managed environment</title>
|
||||||
|
|
||||||
<para>If an EJB3 persistence layer runs in a non-managed environment,
|
<para>If an JPA persistence layer runs in a non-managed environment,
|
||||||
database connections are usually handled by Hibernate's pooling
|
database connections are usually handled by Hibernate's pooling
|
||||||
mechanism behind the scenes. The common entity manager and transaction
|
mechanism behind the scenes. The common entity manager and transaction
|
||||||
handling idiom looks like this:</para>
|
handling idiom looks like this:</para>
|
||||||
|
@ -562,6 +557,11 @@ finally {
|
||||||
<programlisting>//CMT idiom through injection
|
<programlisting>//CMT idiom through injection
|
||||||
@PersistenceContext(name="sample") EntityManager em;</programlisting>
|
@PersistenceContext(name="sample") EntityManager em;</programlisting>
|
||||||
|
|
||||||
|
<para>Or this if you use Java Context and Dependency Injection
|
||||||
|
(CDI).</para>
|
||||||
|
|
||||||
|
<programlisting>@Inject EntityManager em;</programlisting>
|
||||||
|
|
||||||
<para>In other words, all you have to do in a managed environment is to
|
<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,
|
inject the <literal>EntityManager</literal>, do your data access work,
|
||||||
and leave the rest to the container. Transaction boundaries are set
|
and leave the rest to the container. Transaction boundaries are set
|
||||||
|
@ -569,12 +569,7 @@ finally {
|
||||||
session beans. The lifecycle of the entity manager and persistence
|
session beans. The lifecycle of the entity manager and persistence
|
||||||
context is completely managed by the container.</para>
|
context is completely managed by the container.</para>
|
||||||
|
|
||||||
<para>TODO: The following paragraph is very confusing, especially the
|
<para>Due to a silly limitation of the JTA spec, it is not possible for
|
||||||
beginning...</para>
|
|
||||||
|
|
||||||
<para>When using particular Hibernate native APIs, one caveat has to be
|
|
||||||
remembered: <literal>after_statement</literal> connection release mode.
|
|
||||||
Due to a silly limitation of the JTA spec, it is not possible for
|
|
||||||
Hibernate to automatically clean up any unclosed
|
Hibernate to automatically clean up any unclosed
|
||||||
<literal>ScrollableResults</literal> or <literal>Iterator</literal>
|
<literal>ScrollableResults</literal> or <literal>Iterator</literal>
|
||||||
instances returned by <literal>scroll()</literal> or
|
instances returned by <literal>scroll()</literal> or
|
||||||
|
@ -610,23 +605,76 @@ finally {
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>IllegalArgumentException: something wrong happen</para>
|
<para><classname>IllegalArgumentException</classname>: something
|
||||||
|
wrong happen</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>EntityNotFoundException: an entity was expected but none match
|
<para><classname>EntityNotFoundException</classname>: an entity was
|
||||||
the requirement</para>
|
expected but none match the requirement</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>TransactionRequiredException: this operation has to be in a
|
<para><classname>NonUniqueResultException</classname>: more than one
|
||||||
|
entity is found when calling
|
||||||
|
<methodname>getSingleResult()</methodname></para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>NoResultException: when
|
||||||
|
<methodname>getSingleResult()</methodname> does not find any
|
||||||
|
matching entity</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>EntityExistsException</classname>: an existing
|
||||||
|
entity is passed to <methodname>persist()</methodname></para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>TransactionRequiredException</classname>: this
|
||||||
|
operation has to be in a transaction</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>IllegalStateException</classname>: the entity
|
||||||
|
manager is used in a wrong way</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>RollbackException</classname>: a failure happens
|
||||||
|
during <methodname>commit()</methodname></para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>QueryTimeoutException</classname>: the query takes
|
||||||
|
longer than the specified timeout (see
|
||||||
|
<literal>javax.persistence.query.timeout</literal> - this property
|
||||||
|
is a hint and might not be followed)</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>PessimisticLockException</classname>: when a lock
|
||||||
|
cannot be acquired</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>OptimisticLockException</classname>: an optimistic
|
||||||
|
lock is failing</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>LockTimeoutException</classname>: when a lock takes
|
||||||
|
longer than the expected time to be acquired
|
||||||
|
(<literal>javax.persistence.lock.timeout</literal> in
|
||||||
|
milliseconds)</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>TransactionRequiredException</classname>: an
|
||||||
|
operation requiring a transaction is executed outside of a
|
||||||
transaction</para>
|
transaction</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
|
||||||
<para>IllegalStateException: the entity manager is used in a wrong
|
|
||||||
way</para>
|
|
||||||
</listitem>
|
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>The <literal>HibernateException</literal>, which wraps most of the
|
<para>The <literal>HibernateException</literal>, which wraps most of the
|
||||||
|
@ -694,10 +742,10 @@ finally {
|
||||||
<para>In an <literal>EXTENDED</literal> persistence context, all read only
|
<para>In an <literal>EXTENDED</literal> persistence context, all read only
|
||||||
operations of the entity manager can be executed outside a transaction
|
operations of the entity manager can be executed outside a transaction
|
||||||
(<literal>find()</literal>, <literal>getReference()</literal>,
|
(<literal>find()</literal>, <literal>getReference()</literal>,
|
||||||
<literal>refresh()</literal>, and read queries). Some modifications
|
<literal>refresh()</literal>, <methodname>detach()</methodname> and read
|
||||||
operations can be executed outside a transaction, but they are queued
|
queries). Some modifications operations can be executed outside a
|
||||||
until the persistence context join a transaction: this is the case of
|
transaction, but they are queued until the persistence context join a
|
||||||
<literal>persist()</literal>,
|
transaction: this is the case of <literal>persist()</literal>,
|
||||||
<literal><literal>merge()</literal></literal>,
|
<literal><literal>merge()</literal></literal>,
|
||||||
<literal>remove()</literal>. Some operations cannot be called outside a
|
<literal>remove()</literal>. Some operations cannot be called outside a
|
||||||
transaction: <literal>flush()</literal>, <literal>lock()</literal>, and
|
transaction: <literal>flush()</literal>, <literal>lock()</literal>, and
|
||||||
|
@ -706,12 +754,12 @@ finally {
|
||||||
<sect2>
|
<sect2>
|
||||||
<title>Container Managed Entity Manager</title>
|
<title>Container Managed Entity Manager</title>
|
||||||
|
|
||||||
<para>When using an EXTENDED persistence context with a container
|
<para>When using an <literal>EXTENDED</literal> persistence context with
|
||||||
managed entity manager, the lifecycle of the persistence context is
|
a container managed entity manager, the lifecycle of the persistence
|
||||||
binded to the lifecycle of the Stateful Session Bean. Plus if the entity
|
context is binded to the lifecycle of the Stateful Session Bean. Plus if
|
||||||
manager is created outside a transaction, modifications operations
|
the entity manager is created outside a transaction, modifications
|
||||||
(persist, merge, remove) are queued in the persistence context and not
|
operations (persist, merge, remove) are queued in the persistence
|
||||||
executed to the database.</para>
|
context and not executed to the database.</para>
|
||||||
|
|
||||||
<para>When a method of the stateful session bean involved or starting a
|
<para>When a method of the stateful session bean involved or starting a
|
||||||
transaction is later called, the entity manager join the transaction.
|
transaction is later called, the entity manager join the transaction.
|
||||||
|
@ -897,7 +945,7 @@ entityManager.getTransaction().commit();
|
||||||
entityManager.close();</programlisting>
|
entityManager.close();</programlisting>
|
||||||
|
|
||||||
<para>Again, the entity manager will check instance versions during
|
<para>Again, the entity manager will check instance versions during
|
||||||
flush, throwing an exception if conflicting updates occured.</para>
|
flush, throwing an exception if conflicting updates occurred.</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
</sect1>
|
</sect1>
|
||||||
</chapter>
|
</chapter>
|
Loading…
Reference in New Issue