blob: 3b7a44c03e0ba570d4b6582cc2855d3c84420a42 [file] [log] [blame]
<?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://download.oracle.com/javaee/6/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>
Entity locking.
</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>
<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 &lt;T&gt; T find(Class&lt;T&gt; 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 &lt;T&gt; T getReference(Class&lt;T&gt; 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://download.oracle.com/javaee/6/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_locking">
<title>
Entity Locking
</title>
<indexterm zone="jpa_overview_em_locking">
<primary>
EntityManager
</primary>
<secondary>
locking
</secondary>
</indexterm>
<para>
In the area of concurrency control, the JPA specification supports
optimistic and pessimistic locking.
</para>
<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://download.oracle.com/javaee/6/api/javax/persistence/LockModeType.html">
<classname>javax.persistence.LockModeType</classname></ulink> enum defines eight
modes:
</para>
<itemizedlist>
<listitem>
<para>
<literal>OPTIMISTIC</literal>: Optimistic locking.
</para>
</listitem>
<listitem>
<para>
<literal>OPTIMISTIC_FORCE_INCREMENT</literal>: Optimistic locking.
When a transaction is committed, the entity's version column
will be incremented even if the entity's state did not change in the transaction.
</para>
</listitem>
<listitem>
<para>
<literal>PESSIMISTIC_READ</literal>: Pessimistic locking. Other transactions
may concurrently read the entity, but cannot concurrently update it.
</para>
</listitem>
<listitem>
<para>
<literal>PESSIMISTIC_WRITE</literal>: Pessimistic locking. Other transactions
cannot concurrently read or write the entity.
</para>
</listitem>
<listitem>
<para>
<literal>PESSIMISTIC_FORCE_INCREMENT</literal>: Pessimistic locking. Other transactions
cannot concurrently read or write the entity.
When a transaction is committed, the entity's version column
will be incremented even if the entity's state did not change in the transaction.
</para>
</listitem>
<listitem>
<para>
<literal>READ</literal>: A synonym for <literal>OPTIMISTIC</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>WRITE</literal>: A synonym for <literal>OPTIMISTIC_FORCE_INCREMENT</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>NONE</literal>: No locking is performed.
</para>
</listitem>
</itemizedlist>
<para>
Entities can also be locked at the time when entity state gets loaded from the datastore.
This is achieved by supplying a lock mode to the respective versions of
<methodname>find</methodname> and <methodname>refresh</methodname> methods.
If an entity state is to be loaded by a query, a lock mode can be passed to the
<methodname>Query.setLockMode</methodname> and <methodname>TypedQuery.setLockMode</methodname>
methods.
</para>
<programlisting>
public LockModeType getLockMode(Object entity);
</programlisting>
<para>
Returns the lock mode currently held by the given entity.
</para>
<note>
<itemizedlist>
<listitem>
<para>
OpenJPA differentiates between <literal>PESSIMISTIC_READ</literal> and
<literal>PESSIMISTIC_WRITE</literal> lock modes only with DB2 databases.
While running with other databases, there is no distinction between these
two modes because
<literal>PESSIMISTIC_READ</literal> lock mode
is upgraded to <literal>PESSIMISTIC_WRITE</literal>.
</para>
</listitem>
<listitem>
<para>
OpenJPA has additional APIs for controlling entity locking. See
<xref linkend="ref_guide_locking"/> in the Reference Guide for details.
</para>
</listitem>
</itemizedlist>
</note>
</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>