mirror of https://github.com/apache/openjpa.git
1076 lines
35 KiB
XML
1076 lines
35 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!--
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
-->
|
|
<chapter id="jpa_overview_em">
|
|
<title>
|
|
EntityManager
|
|
</title>
|
|
<indexterm zone="jpa_overview_em">
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
</indexterm>
|
|
<mediaobject>
|
|
<imageobject>
|
|
<!-- PNG image data, 283 x 391 (see README) -->
|
|
<imagedata fileref="img/entitymanager.png" width="189px"/>
|
|
|
|
</imageobject>
|
|
</mediaobject>
|
|
<para>
|
|
The diagram above presents an overview of the <classname>EntityManager
|
|
</classname> interface. For a complete treatment of the <classname>
|
|
EntityManager</classname> API, see the
|
|
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/EntityManager.html">
|
|
Javadoc</ulink> documentation. Methods whose parameter signatures consist of
|
|
an ellipsis (...) are overloaded to take multiple parameter types.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
OpenJPA extends the standard <classname>EntityManager</classname> interface with
|
|
the
|
|
<ulink url="../javadoc/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
|
|
<classname>org.apache.openjpa.persistence.OpenJPAEntityManager</classname>
|
|
</ulink> interface to provide additional functionality.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
The <classname>EntityManager</classname> is the primary interface used by
|
|
application developers to interact with the JPA runtime. The methods
|
|
of the <classname>EntityManager</classname> can be divided into the following
|
|
functional categories:
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<classname>Transaction</classname> association.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Entity lifecycle management.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Entity identity management.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Cache management.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<classname>Query</classname> factory.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
Closing.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<section id="jpa_overview_em_trans">
|
|
<title>
|
|
Transaction Association
|
|
</title>
|
|
<indexterm zone="jpa_overview_em_trans">
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
obtaining the Transaction
|
|
</secondary>
|
|
<seealso>
|
|
transactions
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm zone="jpa_overview_em_trans">
|
|
<primary>
|
|
Transaction
|
|
</primary>
|
|
<secondary>
|
|
obtaining from EntityManager
|
|
</secondary>
|
|
</indexterm>
|
|
<programlisting>
|
|
public EntityTransaction getTransaction();
|
|
</programlisting>
|
|
<para>
|
|
Every <classname>EntityManager</classname> has a one-to-one relation with an
|
|
<link linkend="jpa_overview_trans"><classname>EntityTransaction</classname>
|
|
</link> instance. In fact, many vendors use a single class to implement both the
|
|
<classname>EntityManager</classname> and <classname>EntityTransaction
|
|
</classname> interfaces. If your application requires multiple concurrent
|
|
transactions, you will use multiple <classname>EntityManager</classname>s.
|
|
</para>
|
|
<para>
|
|
You can retrieve the <classname>EntityTransaction</classname> associated with an
|
|
<classname>EntityManager</classname> through the <methodname>getTransaction
|
|
</methodname> method. Note that most JPA implementations can
|
|
integrate with an application server's managed transactions. If you take
|
|
advantage of this feature, you will control transactions by declarative
|
|
demarcation or through the Java Transaction API (JTA) rather than through the
|
|
<classname>EntityTransaction</classname>.
|
|
</para>
|
|
</section>
|
|
<section id="jpa_overview_em_lifecycle">
|
|
<title>
|
|
Entity Lifecycle Management
|
|
</title>
|
|
<indexterm zone="jpa_overview_em_lifecycle">
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
lifecycle operations
|
|
</secondary>
|
|
</indexterm>
|
|
<para>
|
|
<classname>EntityManager</classname>s perform several actions that affect the
|
|
lifecycle state of entity instances.
|
|
</para>
|
|
<programlisting>
|
|
public void persist(Object entity);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
persist
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
persist
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
persistent objects
|
|
</primary>
|
|
<secondary>
|
|
persisting
|
|
</secondary>
|
|
</indexterm>
|
|
Transitions new instances to managed. On the next flush or commit, the newly
|
|
persisted instances will be inserted into the datastore.
|
|
</para>
|
|
<para>
|
|
For a given entity <literal>A</literal>, the <methodname>persist</methodname>
|
|
method behaves as follows:
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a new entity, it becomes managed.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is an existing managed entity, it is ignored. However,
|
|
the persist operation cascades as defined below.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a removed entity, it becomes managed.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a detached entity, an <classname>
|
|
IllegalArgumentException</classname> is thrown.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
The persist operation recurses on all relation fields of <literal>A</literal>
|
|
whose <link linkend="jpa_overview_meta_cascade">cascades</link> include
|
|
<literal>CascadeType.PERSIST</literal>.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>
|
|
This action can only be used in the context of an active transaction.
|
|
</para>
|
|
<programlisting>
|
|
public void remove(Object entity);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
remove
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
remove
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
persistent objects
|
|
</primary>
|
|
<secondary>
|
|
deleting
|
|
</secondary>
|
|
</indexterm>
|
|
Transitions managed instances to removed. The instances will be deleted from the
|
|
datastore on the next flush or commit. Accessing a removed entity has undefined
|
|
results.
|
|
</para>
|
|
<para>
|
|
For a given entity <literal>A</literal>, the <methodname>remove</methodname>
|
|
method behaves as follows:
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a new entity, it is ignored. However, the remove
|
|
operation cascades as defined below.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is an existing managed entity, it becomes removed.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a removed entity, it is ignored.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a detached entity, an <classname>
|
|
IllegalArgumentException</classname> is thrown.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
The remove operation recurses on all relation fields of <literal>A</literal>
|
|
whose <link linkend="jpa_overview_meta_cascade">cascades</link> include
|
|
<literal>CascadeType.REMOVE</literal>.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>
|
|
This action can only be used in the context of an active transaction.
|
|
</para>
|
|
<programlisting>
|
|
public void refresh(Object entity);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
refresh
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
refresh
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
persistent objects
|
|
</primary>
|
|
<secondary>
|
|
refreshing state
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
transactions
|
|
</primary>
|
|
<secondary>
|
|
optimistic
|
|
</secondary>
|
|
</indexterm>
|
|
Use the <methodname>refresh</methodname> action to make sure the persistent
|
|
state of an instance is synchronized with the values in the datastore.
|
|
<methodname>refresh</methodname> is intended for long-running optimistic
|
|
transactions in which there is a danger of seeing stale data.
|
|
</para>
|
|
<para>
|
|
For a given entity <literal>A</literal>, the <methodname>refresh</methodname>
|
|
method behaves as follows:
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a new entity, it is ignored. However, the refresh
|
|
operation cascades as defined below.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is an existing managed entity, its state is refreshed
|
|
from the datastore.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a removed entity, it is ignored.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a detached entity, an <classname>
|
|
IllegalArgumentException</classname> is thrown.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
The refresh operation recurses on all relation fields of <literal>A</literal>
|
|
whose <link linkend="jpa_overview_meta_cascade">cascades</link> include
|
|
<literal>CascadeType.REFRESH</literal>.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<programlisting>
|
|
public Object merge(Object entity);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
merge
|
|
</secondary>
|
|
<seealso>
|
|
detachment
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
detachment
|
|
</primary>
|
|
<secondary>
|
|
JPA
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
merge
|
|
</primary>
|
|
<seealso>
|
|
detachment
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
data transfer object
|
|
</primary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
value object
|
|
</primary>
|
|
</indexterm>
|
|
A common use case for an application running in a servlet or application server
|
|
is to "detach" objects from all server resources, modify them, and then "attach"
|
|
them again. For example, a servlet might store persistent data in a user session
|
|
between a modification based on a series of web forms. Between each form
|
|
request, the web container might decide to serialize the session, requiring that
|
|
the stored persistent state be disassociated from any other resources.
|
|
Similarly, a client/server application might transfer persistent objects to a
|
|
client via serialization, allow the client to modify their state, and then have
|
|
the client return the modified data in order to be saved. This is sometimes
|
|
referred to as the <emphasis>data transfer object</emphasis> or <emphasis>value
|
|
object</emphasis> pattern, and it allows fine-grained manipulation of data
|
|
objects without incurring the overhead of multiple remote method invocations.
|
|
</para>
|
|
<para>
|
|
JPA provides support for this pattern by automatically detaching
|
|
entities when they are serialized or when a persistence context ends (see
|
|
<xref linkend="jpa_overview_emfactory_perscontext"/> for an exploration of
|
|
persistence contexts). The JPA <emphasis>merge</emphasis> API
|
|
re-attaches detached entities. This allows you to detach a persistent instance,
|
|
modify the detached instance offline, and merge the instance back into an
|
|
<classname>EntityManager</classname> (either the same one that detached the
|
|
instance, or a new one). The changes will then be applied to the existing
|
|
instance from the datastore.
|
|
</para>
|
|
<para>
|
|
A detached entity maintains its persistent identity, but cannot load additional
|
|
state from the datastore. Accessing any persistent field or property that was
|
|
not loaded at the time of detachment has undefined results. Also, be sure not to
|
|
alter the version or identity fields of detached instances if you plan on
|
|
merging them later.
|
|
</para>
|
|
<para>
|
|
The <methodname>merge</methodname> method returns a managed copy of the given
|
|
detached entity. Changes made to the persistent state of the detached entity are
|
|
applied to this managed instance. Because merging involves changing persistent
|
|
state, you can only merge within a transaction.
|
|
</para>
|
|
<para>
|
|
If you attempt to merge an instance whose representation has changed in the
|
|
datastore since detachment, the merge operation will throw an exception, or the
|
|
transaction in which you perform the merge will fail on commit, just as if a
|
|
normal optimistic conflict were detected.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
OpenJPA offers enhancements to JPA detachment functionality,
|
|
including additional options to control which fields are detached. See
|
|
<xref linkend="ref_guide_detach"/> in the Reference Guide for details.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
For a given entity <literal>A</literal>, the <methodname>merge</methodname>
|
|
method behaves as follows:
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a detached entity, its state is copied into existing
|
|
managed instance <literal>A'</literal> of the same entity identity, or a new
|
|
managed copy of <literal>A</literal> is created.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a new entity, a new managed entity <literal>A'
|
|
</literal> is created and the state of <literal>A</literal> is copied into
|
|
<literal>A'</literal>.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is an existing managed entity, it is ignored. However,
|
|
the merge operation still cascades as defined below.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
If <literal>A</literal> is a removed entity, an <classname>
|
|
IllegalArgumentException</classname> is thrown.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
The merge operation recurses on all relation fields of <literal>A</literal>
|
|
whose <link linkend="jpa_overview_meta_cascade">cascades</link> include
|
|
<literal>CascadeType.MERGE</literal>.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<programlisting>
|
|
public void lock(Object entity, LockModeType mode);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
lock
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
locking
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
This method locks the given entity using the named mode. The
|
|
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/LockmodeType.html">
|
|
<classname>javax.persistence.LockModeType</classname></ulink> enum defines two
|
|
modes:
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<literal>READ</literal>: Other transactions may concurrently read the object,
|
|
but cannot concurrently update it.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<literal>WRITE</literal>: Other transactions cannot concurrently read or write
|
|
the object. When a transaction is committed that holds WRITE locks on any
|
|
entities, those entities will have their version incremented even if the entities
|
|
themselves did not change in the transaction.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<note>
|
|
<para>
|
|
OpenJPA has additional APIs for controlling object locking. See
|
|
<xref linkend="ref_guide_locking"/> in the Reference Guide for details.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
The following diagram illustrates the lifecycle of an entity with respect to the
|
|
APIs presented in this section.
|
|
</para>
|
|
<mediaobject>
|
|
<imageobject>
|
|
<!-- PNG image data, 445 x 337 (see README) -->
|
|
<imagedata fileref="img/jpa-state-transitions.png" width="297px"/>
|
|
|
|
</imageobject>
|
|
</mediaobject>
|
|
</section>
|
|
<section id="jpa_overview_em_lifeexamples">
|
|
<title>
|
|
Lifecycle Examples
|
|
</title>
|
|
<para>
|
|
The examples below demonstrate how to use the lifecycle methods presented in the
|
|
previous section. The examples are appropriate for out-of-container use. Within
|
|
a container, <classname> EntityManager</classname>s are usually injected, and
|
|
transactions are usually managed. You would therefore omit the <methodname>
|
|
createEntityManager</methodname> and <methodname>close</methodname> calls, as
|
|
well as all transaction demarcation code.
|
|
</para>
|
|
<example id="jpa_overview_em_lifecycle_persist">
|
|
<title>
|
|
Persisting Objects
|
|
</title>
|
|
<indexterm>
|
|
<primary>
|
|
persistent objects
|
|
</primary>
|
|
<secondary>
|
|
persisting
|
|
</secondary>
|
|
<tertiary>
|
|
example
|
|
</tertiary>
|
|
</indexterm>
|
|
<programlisting>
|
|
// create some objects
|
|
Magazine mag = new Magazine("1B78-YU9L", "JavaWorld");
|
|
|
|
Company pub = new Company("Weston House");
|
|
pub.setRevenue(1750000D);
|
|
mag.setPublisher(pub);
|
|
pub.addMagazine(mag);
|
|
|
|
Article art = new Article("JPA Rules!", "Transparent Object Persistence");
|
|
art.addAuthor(new Author("Fred", "Hoyle"));
|
|
mag.addArticle(art);
|
|
|
|
// persist
|
|
EntityManager em = emf.createEntityManager();
|
|
em.getTransaction().begin();
|
|
em.persist(mag);
|
|
em.persist(pub);
|
|
em.persist(art);
|
|
em.getTransaction().commit();
|
|
|
|
// or we could continue using the EntityManager...
|
|
em.close();
|
|
</programlisting>
|
|
</example>
|
|
<example id="jpa_overview_em_lifecycle_update">
|
|
<title>
|
|
Updating Objects
|
|
</title>
|
|
<indexterm>
|
|
<primary>
|
|
persistent objects
|
|
</primary>
|
|
<secondary>
|
|
updating
|
|
</secondary>
|
|
<tertiary>
|
|
example
|
|
</tertiary>
|
|
</indexterm>
|
|
<programlisting>
|
|
Magazine.MagazineId mi = new Magazine.MagazineId();
|
|
mi.isbn = "1B78-YU9L";
|
|
mi.title = "JavaWorld";
|
|
|
|
// updates should always be made within transactions; note that
|
|
// there is no code explicitly linking the magazine or company
|
|
// with the transaction; JPA automatically tracks all changes
|
|
EntityManager em = emf.createEntityManager();
|
|
em.getTransaction().begin();
|
|
Magazine mag = em.find(Magazine.class, mi);
|
|
mag.setPrice(5.99);
|
|
Company pub = mag.getPublisher();
|
|
pub.setRevenue(1750000D);
|
|
em.getTransaction().commit();
|
|
|
|
// or we could continue using the EntityManager...
|
|
em.close();
|
|
</programlisting>
|
|
</example>
|
|
<example id="jpa_overview_em_lifecycle_delete">
|
|
<title>
|
|
Removing Objects
|
|
</title>
|
|
<indexterm>
|
|
<primary>
|
|
persistent objects
|
|
</primary>
|
|
<secondary>
|
|
deleting
|
|
</secondary>
|
|
<tertiary>
|
|
example
|
|
</tertiary>
|
|
</indexterm>
|
|
<programlisting>
|
|
// assume we have an object id for the company whose subscriptions
|
|
// we want to delete
|
|
Object oid = ...;
|
|
|
|
// deletes should always be made within transactions
|
|
EntityManager em = emf.createEntityManager();
|
|
em.getTransaction().begin();
|
|
Company pub = (Company) em.find(Company.class, oid);
|
|
for (Subscription sub : pub.getSubscriptions())
|
|
em.remove(sub);
|
|
pub.getSubscriptions().clear();
|
|
em.getTransaction().commit();
|
|
|
|
// or we could continue using the EntityManager...
|
|
em.close();
|
|
</programlisting>
|
|
</example>
|
|
<example id="jpa_overview_em_detachex">
|
|
<title>
|
|
Detaching and Merging
|
|
</title>
|
|
<para>
|
|
This example demonstrates a common client/server scenario. The client requests
|
|
objects and makes changes to them, while the server handles the object lookups
|
|
and transactions.
|
|
</para>
|
|
<programlisting>
|
|
// CLIENT:
|
|
// requests an object with a given oid
|
|
Record detached = (Record) getFromServer(oid);
|
|
|
|
...
|
|
|
|
// SERVER:
|
|
// send object to client; object detaches on EM close
|
|
Object oid = processClientRequest();
|
|
EntityManager em = emf.createEntityManager();
|
|
Record record = em.find(Record.class, oid);
|
|
em.close();
|
|
sendToClient(record);
|
|
|
|
...
|
|
|
|
// CLIENT:
|
|
// makes some modifications and sends back to server
|
|
detached.setSomeField("bar");
|
|
sendToServer(detached);
|
|
|
|
...
|
|
|
|
// SERVER:
|
|
// merges the instance and commit the changes
|
|
Record modified = (Record) processClientRequest();
|
|
EntityManager em = emf.createEntityManager();
|
|
em.getTransaction().begin();
|
|
Record merged = (Record) em.merge(modified);
|
|
merged.setLastModified(System.currentTimeMillis());
|
|
merged.setModifier(getClientIdentityCode());
|
|
em.getTransaction().commit();
|
|
em.close();
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
<section id="jpa_overview_em_identity">
|
|
<title>
|
|
Entity Identity Management
|
|
</title>
|
|
<para>
|
|
Each <classname>EntityManager</classname> is responsible for managing the
|
|
persistent identities of the managed objects in the persistence context. The
|
|
following methods allow you to interact with the management of persistent
|
|
identities. The behavior of these methods is deeply affected by the persistence
|
|
context type of the <classname>EntityManager</classname>; see
|
|
<xref linkend="jpa_overview_emfactory_perscontext"/> for an explanation of
|
|
persistence contexts.
|
|
</para>
|
|
<programlisting>
|
|
public <T> T find(Class<T> cls, Object oid);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
find
|
|
</secondary>
|
|
<seealso>
|
|
identity
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
find
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
identity
|
|
</primary>
|
|
<secondary>
|
|
retrieving objects by identity
|
|
</secondary>
|
|
</indexterm>
|
|
This method returns the persistent instance of the given type with the given
|
|
persistent identity. If the instance is already present in the current
|
|
persistence context, the cached version will be returned. Otherwise, a new
|
|
instance will be constructed and loaded with state from the datastore. If no
|
|
entity with the given type and identity exists in the datastore, this method
|
|
returns null.
|
|
</para>
|
|
<programlisting>
|
|
public <T> T getReference(Class<T> cls, Object oid);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
getReference
|
|
</secondary>
|
|
<seealso>
|
|
identity
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
getReference
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
identity
|
|
</primary>
|
|
<secondary>
|
|
retrieving objects by identity
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
EntityNotFoundException
|
|
</primary>
|
|
</indexterm>
|
|
This method is similar to <methodname>find</methodname>, but does not
|
|
necessarily go to the database when the entity is not found in cache. The
|
|
implementation may construct a <emphasis>hollow</emphasis> entity and return it
|
|
to you instead. Hollow entities do not have any state loaded. The state only
|
|
gets loaded when you attempt to access a persistent field. At that time, the
|
|
implementation may throw an <classname>EntityNotFoundException</classname> if it
|
|
discovers that the entity does not exist in the datastore. The implementation
|
|
may also throw an <classname>EntityNotFoundException</classname> from the
|
|
<methodname>getReference</methodname> method itself. Unlike <methodname>
|
|
find</methodname>, <methodname>getReference</methodname> does not return null.
|
|
</para>
|
|
<programlisting>
|
|
public boolean contains(Object entity);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
contains
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
contains
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
Returns true if the given entity is part of the current persistence context, and
|
|
false otherwise. Removed entities are not considered part of the current
|
|
persistence context.
|
|
</para>
|
|
</section>
|
|
<section id="jpa_overview_em_cache">
|
|
<title>
|
|
Cache Management
|
|
</title>
|
|
<indexterm zone="jpa_overview_em_cache">
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
cache
|
|
</secondary>
|
|
</indexterm>
|
|
<programlisting>
|
|
public void flush();
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
flush
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
flush
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
transactions
|
|
</primary>
|
|
<secondary>
|
|
flushing changes before commit
|
|
</secondary>
|
|
</indexterm>
|
|
The <methodname>flush</methodname> method writes any changes that have been made
|
|
in the current transaction to the datastore. If the <classname>EntityManager
|
|
</classname> does not already have a connection to the datastore, it obtains one
|
|
for the flush and retains it for the duration of the transaction. Any exceptions
|
|
during flush cause the transaction to be marked for rollback. See
|
|
<xref linkend="jpa_overview_trans"/>.
|
|
</para>
|
|
<para>
|
|
Flushing requires an active transaction. If there isn't a transaction in
|
|
progress, the <methodname>flush</methodname> method throws a <classname>
|
|
TransactionRequiredException</classname>.
|
|
</para>
|
|
<programlisting>
|
|
public FlushModeType getFlushMode();
|
|
public void setFlushMode(FlushModeType flushMode);
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
FlushMode
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
FlushMode
|
|
</primary>
|
|
</indexterm>
|
|
The <classname>EntityManager</classname>'s <literal>FlushMode</literal> property
|
|
controls whether to flush transactional changes before executing queries. This
|
|
allows the query results to take into account changes you have made during the
|
|
current transaction. Available
|
|
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/FlushModeType.html">
|
|
<classname>javax.persistence.FlushModeType</classname></ulink> constants are:
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>
|
|
<literal>COMMIT</literal>: Only flush when committing, or when told to do so
|
|
through the <methodname>flush</methodname> method. Query results may not take
|
|
into account changes made in the current transaction.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>
|
|
<literal>AUTO</literal>: The implementation is permitted to flush before
|
|
queries to ensure that the results reflect the most recent object state.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
<para>
|
|
You can also set the flush mode on individual
|
|
<link linkend="jpa_overview_query"><classname>Query</classname></link>
|
|
instances.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
OpenJPA only flushes before a query if the query might be affected by data
|
|
changed in the current transaction. Additionally, OpenJPA allows fine-grained
|
|
control over flushing behavior. See the Reference Guide's
|
|
<xref linkend="ref_guide_dbsetup_retain"/>.
|
|
</para>
|
|
</note>
|
|
<programlisting>
|
|
public void clear();
|
|
</programlisting>
|
|
<para>
|
|
<indexterm>
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
clear
|
|
</secondary>
|
|
</indexterm>
|
|
<indexterm>
|
|
<primary>
|
|
clear
|
|
</primary>
|
|
<seealso>
|
|
EntityManager
|
|
</seealso>
|
|
</indexterm>
|
|
Clearing the <classname>EntityManager</classname> effectively ends the
|
|
persistence context. All entities managed by the <classname>EntityManager
|
|
</classname> become detached.
|
|
</para>
|
|
</section>
|
|
<section id="jpa_overview_em_query">
|
|
<title>
|
|
Query Factory
|
|
</title>
|
|
<indexterm zone="jpa_overview_em_query">
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
as Query factory
|
|
</secondary>
|
|
<seealso>
|
|
Query
|
|
</seealso>
|
|
</indexterm>
|
|
<indexterm zone="jpa_overview_em_query">
|
|
<primary>
|
|
Query
|
|
</primary>
|
|
<secondary>
|
|
creating
|
|
</secondary>
|
|
</indexterm>
|
|
<programlisting>
|
|
public Query createQuery(String query);
|
|
</programlisting>
|
|
<para>
|
|
<classname>Query</classname> objects are used to find entities matching certain
|
|
criteria. The <methodname>createQuery</methodname> method creates a query using
|
|
the given Java Persistence Query Language (JPQL) string. See
|
|
<xref linkend="jpa_overview_query"/> for details.
|
|
</para>
|
|
<programlisting>
|
|
public Query createNamedQuery(String name);
|
|
</programlisting>
|
|
<para>
|
|
This method retrieves a query defined in metadata by name. The returned
|
|
<classname>Query</classname> instance is initialized with the information
|
|
declared in metadata. For more information on named queries, read
|
|
<xref linkend="jpa_overview_query_named"/>.
|
|
</para>
|
|
<programlisting>
|
|
public Query createNativeQuery(String sql);
|
|
public Query createNativeQuery(String sql, Class resultCls);
|
|
public Query createNativeQuery(String sql, String resultMapping);
|
|
</programlisting>
|
|
<para>
|
|
<emphasis>Native</emphasis> queries are queries in the datastore's native
|
|
language. For relational databases, this is the Structured Query Language (SQL).
|
|
<xref linkend="jpa_overview_sqlquery"/> elaborates on JPA's
|
|
native query support.
|
|
</para>
|
|
</section>
|
|
<section id="jpa_overview_em_properties">
|
|
<title>
|
|
Retrieving Properties Information
|
|
</title>
|
|
<indexterm zone="jpa_overview_em_properties">
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
properties information
|
|
</secondary>
|
|
</indexterm>
|
|
&properties_info.xml;
|
|
</section>
|
|
<section id="jpa_overview_em_closing">
|
|
<title>
|
|
Closing
|
|
</title>
|
|
<indexterm zone="jpa_overview_em_closing">
|
|
<primary>
|
|
EntityManager
|
|
</primary>
|
|
<secondary>
|
|
closing
|
|
</secondary>
|
|
</indexterm>
|
|
<programlisting>
|
|
public boolean isOpen();
|
|
public void close();
|
|
</programlisting>
|
|
<para>
|
|
When an <classname>EntityManager</classname> is no longer needed, you should
|
|
call its <methodname>close</methodname> method. Closing an <classname>
|
|
EntityManager</classname> releases any resources it is using. The persistence
|
|
context ends, and the entities managed by the <classname>EntityManager
|
|
</classname> become detached. Any <classname>Query</classname> instances the
|
|
<classname>EntityManager</classname> created become invalid. Calling any method
|
|
other than <methodname>isOpen</methodname> on a closed <classname>EntityManager
|
|
</classname> results in an <classname>IllegalStateException</classname>. You
|
|
cannot close a <classname>EntityManager</classname> that is in the middle of a
|
|
transaction.
|
|
</para>
|
|
<para>
|
|
If you are in a managed environment using injected entity managers, you should
|
|
not close them.
|
|
</para>
|
|
</section>
|
|
</chapter>
|