In its default configuration, OpenJPA obtains JDBC connections on an as-needed
basis. OpenJPA EntityManager
s do not retain a connection
to the database unless they are in a datastore transaction or there are open
Query
results that are using a live JDBC result set. At
all other times, including during optimistic transactions,
EntityManager
s request a connection for each query, then
immediately release the connection back to the pool.
In some cases, it may be more efficient to retain connections for longer periods
of time. You can configure OpenJPA's use of JDBC connections through the
openjpa.ConnectionRetainMode
configuration property. The
property accepts the following values:
always
: Each EntityManager
obtains a
single connection and uses it until the EntityManager
closes. Great care should be taken when using this property if the application
cannot close the EntityManager (i.e. container-managed EntityManagers in a JEE
Application Server). In this case the connection will remain open for an
undefined time and the application may not be able to recover from a terminated
connection (for example, if a TCP/IP timeout severs the connection to the database).
For this reason the always
option should not be used with
container-managed EntityManagers.
transaction
: A connection is obtained when each transaction
begins (optimistic or datastore), and is released when the transaction
completes. Non-transactional connections are obtained on-demand.
on-demand
: Connections are obtained only when needed. This
option is equivalent to the transaction
option when datastore
transactions are used. For optimistic transactions, though, it means that a
connection will be retained only for the duration of the datastore flush and
commit process.
You can also specify the connection retain mode of individual
EntityManager
s when you retrieve them from the
EntityManagerFactory
. See
Section 2.1, “
OpenJPAEntityManagerFactory
” for details.
The
openjpa.FlushBeforeQueries
configuration property controls
another aspect of connection usage: whether to flush transactional changes
before executing object queries. This setting only applies to queries that would
otherwise have to be executed in-memory because the
IgnoreChanges
property is set to false and the query may involve objects that have been
changed in the current transaction. Legal values are:
true
: Always flush rather than executing the query
in-memory. If the current transaction is optimistic, OpenJPA will begin a
non-locking datastore transaction. This is the default.
false
: Never flush before a query.
with-connection
: Flush only if the EntityManager
has already established a dedicated connection to the datastore,
otherwise execute the query in-memory.
This option is useful if you use long-running optimistic transactions and want
to ensure that these transactions do not consume database resources until
commit. OpenJPA's behavior with this option is dependent on the transaction
status and mode, as well as the configured connection retain mode described
earlier in this section.
The flush mode can also be varied at runtime using the OpenJPA fetch configuration API, discussed in Chapter 9, Runtime Extensions .
The table below describes the behavior of automatic flushing in various situations. In all cases, flushing will only occur if OpenJPA detects that you have made modifications in the current transaction that may affect the query's results.
Table 4.2. OpenJPA Automatic Flush Behavior
FlushBeforeQueries = false | FlushBeforeQueries = true | FlushBeforeQueries = with-connection; ConnectionRetainMode = on-demand | FlushBeforeQueries = with-connection; ConnectionRetainMode = transaction or always | |
---|---|---|---|---|
IgnoreChanges = true | no flush | no flush | no flush | no flush |
IgnoreChanges = false; no tx active | no flush | no flush | no flush | no flush |
IgnoreChanges = false; datastore tx active | no flush | flush | flush | flush |
IgnoreChanges = false; optimistic tx active | no flush | flush |
no flush unless flush has already been invoked
| flush |
Example 4.10. Specifying Connection Usage Defaults
<property name="openjpa.ConnectionRetainMode" value="on-demand"/> <property name="openjpa.FlushBeforeQueries" value="true"/>
Example 4.11. Specifying Connection Usage at Runtime
import org.apache.openjpa.persistence.*; // obtaining an em with a certain connection retain mode Map props = new HashMap(); props.put("openjpa.ConnectionRetainMode", "always"); EntityManager em = emf.createEntityManager(props);