openjpa/openjpa-project/src/doc/manual/ref_guide_dbsetup.xml

2862 lines
147 KiB
XML
Raw Normal View History

<chapter id="ref_guide_dbsetup">
<title>JDBC</title>
<indexterm zone="ref_guide_dbsetup">
<primary>JDBC</primary>
</indexterm>
<para>
OpenJPA <phrase>JPA</phrase> uses a relational database for object persistence. It
communicates with the database using the Java DataBase Connectivity (JDBC)
APIs. This chapter describes how to configure OpenJPA to work with the
JDBC driver for your database, and how to access JDBC functionality at
runtime.
</para>
<section id="ref_guide_dbsetup_builtin">
<title>Using the OpenJPA DataSource</title>
<indexterm zone="ref_guide_dbsetup_builtin">
<primary>DataSource</primary>
<secondary>OpenJPA</secondary>
</indexterm>
<indexterm>
<primary>connections</primary>
<seealso>DataSource</seealso>
</indexterm>
<para>
OpenJPA includes its own <classname>javax.sql.DataSource</classname>
implementation, complete with configurable connection pooling
and prepared statement caching. If you choose to use
OpenJPA's <classname>DataSource</classname>, then you must specify
the following properties:
</para>
<itemizedlist>
<listitem>
<para><indexterm><primary>ConnectionUserName</primary></indexterm><literal>openjpa.ConnectionUserName</literal>:
The JDBC user name for connecting to the database.
</para>
</listitem>
<listitem>
<para><indexterm><primary>ConnectionPassword</primary></indexterm><literal>openjpa.ConnectionPassword</literal>:
The JDBC password for the above user.
</para>
</listitem>
<listitem>
<para><indexterm><primary>ConnectionURL</primary></indexterm><literal>openjpa.ConnectionURL</literal>:
The JDBC URL for the database.
</para>
</listitem>
<listitem>
<para><indexterm><primary>ConnectionDriverName</primary></indexterm><literal>openjpa.ConnectionDriverName</literal>:
The JDBC driver class.
</para>
</listitem>
</itemizedlist>
<para>
To configure advanced features such as connection pooling and prepared
statement caching, or to configure the underlying JDBC driver, use the
following optional properties. The syntax of these property strings
follows the syntax of OpenJPA plugin parameters described in
<xref linkend="ref_guide_conf_plugins"/>.
</para>
<itemizedlist>
<listitem>
<para><indexterm><primary>ConnectionProperties</primary></indexterm><link linkend="openjpa.ConnectionProperties"><literal>openjpa.ConnectionProperties</literal></link>:
If the listed driver is an instance of
<classname>java.sql.Driver</classname>, this string will
be parsed into a <classname>Properties</classname> instance,
which will then be used to obtain database connections through
the <methodname>Driver.connect(String url,
Properties props)</methodname> method. If, on the other hand,
the listed driver is a <classname>
javax.sql.DataSource</classname>,
the string will be treated as a plugin properties string, and
matched to the bean setter methods of the
<classname>DataSource</classname> instance.
</para>
</listitem>
<listitem>
<para><indexterm><primary>ConnectionFactoryProperties</primary></indexterm><link linkend="openjpa.ConnectionFactoryProperties"><literal>openjpa.ConnectionFactoryProperties</literal></link>:
OpenJPA's built-in <classname>DataSource</classname>
allows you to set the following options via
this plugin string:
</para>
<itemizedlist>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>ExceptionAction</tertiary></indexterm><literal>ExceptionAction</literal>: The action to
take when when a connection that has thrown an exception
is returned to the pool. Set to <literal>destroy
</literal> to destroy the connection. Set to <literal>
validate</literal> to validate the connection (subject
to the <literal>TestOnReturn</literal>, <literal>
TestOnBorrow</literal>, and other test settings).
Set to <literal>none</literal> to ignore the fact that
the connection has thrown an exception, and assume it
is still usable. Defaults to <literal>
destroy</literal>.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>MaxActive</tertiary></indexterm><literal>MaxActive</literal>: The maximum number of
database connections in use at one time. A value of 0
disables connection pooling. Defaults to 8.
This is the maximum number of connections that OpenJPA will
give out to your application. If a connection is
requested while <literal>MaxActive</literal> other
connections are in use, OpenJPA will wait for
<literal>MaxWait</literal> milliseconds for a connection
to be returned, and will then throw an exception if no
connection was made available.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>MaxIdle</tertiary></indexterm><literal>MaxIdle</literal>: The maximum number of
idle database connections to keep in the pool. Defaults
to 8. If this number is less than
<literal>MaxActive</literal>, then OpenJPA will close
extra connections that are returned to the pool if
there are already <literal>MaxIdle</literal> available
connections. This allows for
unexpected or atypical load while still maintaining
a relatively small pool when there is less load on the
system.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>MaxTotal</tertiary></indexterm><literal>MaxTotal</literal>: The maximum number of
database connections in the pool, whether active or
idle. Defaults to -1, meaning no limit (the limit will
be dictated by <literal>MaxActive</literal> and
<literal>MaxIdle</literal> for each unique user name).
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>MaxWait</tertiary></indexterm><literal>MaxWait</literal>: The maximum number of
milliseconds to wait for a free database connection to
become available before giving up. Defaults to 3000.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>MinEvictableIdleTimeMillis</tertiary></indexterm><literal>MinEvictableIdleTimeMillis</literal>: The
minimum number of milliseconds that a database
connection can sit idle before it becomes a candidate
for eviction from the pool. Defaults to 30 minutes.
Set to 0 to never evict a connection based on idle
time alone.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>RollbackOnReturn</tertiary></indexterm><literal>RollbackOnReturn</literal>:
Force all connections to be rolled back when they
are retuned to the pool. If false, the <classname>
DataSource</classname> will
only roll back connections when it detects that there
have been any transactional updates on the connection.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>TestOnBorrow</tertiary></indexterm><literal>TestOnBorrow</literal>: Whether to to validate
database connections before obtaining them from the
pool. Note that validation
only consists of a call to the connection's
<methodname>isClosed</methodname> method unless you
specify a <literal>ValidationSQL</literal> string.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>TestOnReturn</tertiary></indexterm><literal>TestOnReturn</literal>: Set to <literal>true
</literal> to validate database connections when they
are returned to the pool. Note that validation
only consists of a call to the connection's
<methodname>isClosed</methodname> method unless you
specify a <literal>ValidationSQL</literal> string.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>TestWhileIdle</tertiary></indexterm><literal>TestWhileIdle</literal>: Set to
<literal>true</literal> to periodically validate idle
database connections.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>TimeBetweenEvictionRunsMillis</tertiary></indexterm><literal>TimeBetweenEvictionRunsMillis</literal>: The
number of milliseconds between runs of the eviction
thread. Defaults to <literal>-1</literal>, meaning
the eviction thread will never run.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>TrackParameters</tertiary></indexterm><literal>TrackParameters</literal>: When
<literal>true</literal>, OpenJPA will track the
parameters that were set for all
<classname>PreparedStatement</classname>s that
are executed or batched so that they can be
included in error messages.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>ValidationSQL</tertiary></indexterm><literal>ValidationSQL</literal>: A simple SQL query to
issue to validate a database connection. If this
property is not set, then the only validation performed
is to use the <methodname>Connection.isClosed
</methodname> method. The following table shows the
default settings for different databases. If a database
is not shown, this property defaults to null.
</para>
<table>
<title>Validation SQL Defaults</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="db"/>
<colspec colname="sql"/>
<thead>
<row>
<entry colname="db">Database</entry>
<entry colname="sql">SQL</entry>
</row>
</thead>
<tbody>
<row>
<entry colname="db">DB2</entry>
<entry colname="sql">
SELECT DISTINCT(CURRENT TIMESTAMP)
FROM SYSIBM.SYSTABLES
</entry>
</row>
<row>
<entry colname="db">Empress</entry>
<entry colname="sql">
SELECT DISTINCT(TODAY)
FROM SYS_TABLES
</entry>
</row>
<row>
<entry colname="db">Informix</entry>
<entry colname="sql">
SELECT DISTINCT CURRENT TIMESTAMP
FROM INFORMIX.SYSTABLES
</entry>
</row>
<row>
<entry colname="db">MySQL</entry>
<entry colname="sql">
SELECT NOW()
</entry>
</row>
<row>
<entry colname="db">Oracle</entry>
<entry colname="sql">
SELECT SYSDATE FROM DUAL
</entry>
</row>
<row>
<entry colname="db">Postgres</entry>
<entry colname="sql">
SELECT NOW()
</entry>
</row>
<row>
<entry colname="db">SQLServer</entry>
<entry colname="sql">
SELECT GETDATE()
</entry>
</row>
<row>
<entry colname="db">Sybase</entry>
<entry colname="sql">
SELECT GETDATE()
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
To disable validation SQL, set this property to
an empty string, as in
<xref linkend="ref_guide_dbsetup_builtin_ex"/>
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>ClosePoolSQL</tertiary></indexterm><literal>ClosePoolSQL</literal>: A simple SQL statement
to execute when the connection pool is completely
closed. This can be used, for example, to cleanly
issue a shutdown statement to a file-based
database.
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>ValidationTimeout</tertiary></indexterm><literal>ValidationTimeout</literal>:
The minimum number of milliseconds that must elapse
before a connection will ever be re-validated. This
property is typically used with <literal>TestOnBorrow
</literal> or <literal>TestOnReturn</literal> to
reduce the number of validations performed, because
the same connection is often borrowed and returned many
times in a short span. Defaults to
<literal>300000</literal> (5 minutes).
</para>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>WarningAction</tertiary></indexterm><literal>WarningAction</literal>:
The action to take when a
<classname>SQLWarning</classname> is detected on a
connection. Possible values are:
</para>
<itemizedlist>
<listitem>
<para><literal>ignore</literal>: Warnings will
not be checked for, and will be ignored.
This is the default.
</para>
</listitem>
<listitem>
<para><literal>trace</literal>:
The warning will be logged on the
<literal>TRACE</literal>
channel of the JDBC log.
</para>
</listitem>
<listitem>
<para><literal>info</literal>:
The warning will be logged on the
<literal>INFO</literal>
channel of the JDBC log.
</para>
</listitem>
<listitem>
<para><literal>warn</literal>:
The warning will be logged on the
<literal>WARN</literal>
channel of the JDBC log.
</para>
</listitem>
<listitem>
<para><literal>error</literal>:
The warning will be logged on the
<literal>ERROR</literal>
channel of the JDBC log.
</para>
</listitem>
<listitem>
<para><literal>throw</literal>:
All <classname>SQLWarning</classname>
instances will be thrown as if they were
errors.
</para>
</listitem>
<listitem>
<para><literal>handle</literal>:
The <classname>SQLWarning</classname>
instance will be passed through the
<methodname>handleWarning</methodname>
method of
<ulink url="javadoc/openjpa/jdbc/sql/DBDictionary.html"><classname>
org.apache.openjpa.jdbc.sql.DBDictionary</classname></ulink>,
which allows a custom extension
of the dictionary to use heuristic-based
warning handling.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><indexterm><primary>connections</primary><secondary>pooling</secondary><tertiary>WhenExhaustedAction</tertiary></indexterm><literal>WhenExhaustedAction</literal>: The action to
take when there are no available database connections
in the pool. Set to <literal>exception</literal> to
immediately throw an exception. Set to <literal>
block</literal> to block until a connection is
available or the maximum wait time is exceeded. Set to
<literal>grow</literal> to automatically grow the pool.
Defaults to <literal>block</literal>.
</para>
</listitem>
</itemizedlist>
<para>
Additionally, the following properties are available whether
you use OpenJPA's built-in <classname>DataSource</classname>
or a third-party's:
</para>
<itemizedlist>
<listitem>
<para><indexterm><primary>prepared statement</primary><secondary>pooling</secondary><tertiary>MaxCachedStatements</tertiary></indexterm><literal>MaxCachedStatements</literal>: The maximum
number of
<classname>java.sql.PreparedStatement</classname>s
to cache. Statement caching can dramatically speed up
some databases. Defaults to 50 for OpenJPA's
<classname>DataSource</classname>, and 0 for
third-party <classname>DataSource</classname>s. Most
third-party <classname>DataSource</classname>s do not
benefit from OpenJPA's prepared statement cache, because
each returned connection has a unique hash code,
making it impossible for OpenJPA to match connections to
their cached statements.
</para>
</listitem>
<listitem>
<para><indexterm><primary>JDBC</primary><secondary>QueryTimeout</secondary></indexterm><literal>QueryTimeout</literal>: The maximum number of
seconds the JDBC driver will wait for a statement to
execute.
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<example id="ref_guide_dbsetup_builtin_ex">
<title>Properties for the OpenJPA DataSource</title>
<programlisting format="linespecific">
&lt;property name="openjpa.ConnectionUserName" value="user"/&gt;
&lt;property name="openjpa.ConnectionPassword" value="pass"/&gt;
&lt;property name="openjpa.ConnectionURL" value="jdbc:hsqldb:db-hypersonic"/&gt;
&lt;property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/&gt;
&lt;property name="openjpa.ConnectionFactoryProperties"
value="MaxActive=50, MaxIdle=10, ValidationTimeout=50000, MaxCachedStatements=100, ValidationSQL=''"/&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_dbsetup_thirdparty">
<title>Using a Third-Party DataSource</title>
<indexterm zone="ref_guide_dbsetup_builtin">
<primary>DataSource</primary>
<secondary>third party</secondary>
</indexterm>
<para>
You can use OpenJPA with any third-party
<classname>javax.sql.DataSource</classname>. There are multiple ways
of telling OpenJPA about a <classname>DataSource</classname>:
</para>
<itemizedlist>
<listitem>
<para><indexterm><primary>ConnectionFactory</primary></indexterm>
Set the <classname>DataSource</classname> into the map passed
to <methodname>Persistence.createEntityManagerFactory
</methodname> under the <link linkend="openjpa.ConnectionFactory"><literal>openjpa.ConnectionFactory</literal></link> key.
</para>
</listitem>
<listitem>
<para><indexterm><primary>ConnectionFactoryName</primary></indexterm>
Bind the <classname>DataSource</classname> into JNDI, and then
specify its location in the
<phrase><literal>jta-data-source</literal> or
<literal>non-jta-data-source</literal> element of the
<link linkend="jpa_overview_persistence_xml">JPA XML
format</link> (depending on whether the <classname>DataSource
</classname> is managed by JTA), or in the
</phrase><link linkend="openjpa.ConnectionFactoryName"><literal>openjpa.ConnectionFactoryName</literal></link> property.
</para>
</listitem>
<listitem>
<para><indexterm><primary>ConnectionDriverName</primary></indexterm>
Specify the full class name of the
<classname>DataSource</classname> implementation in the
<link linkend="openjpa.ConnectionDriverName"><literal>openjpa.ConnectionDriverName</literal></link> property
in place of a JDBC driver. In this configuration OpenJPA will
instantiate an instance of the named class via reflection. It
will then configure the <classname>DataSource</classname> with
the properties in the <link linkend="openjpa.ConnectionProperties"><literal>openjpa.ConnectionProperties</literal></link> setting.
</para>
</listitem>
</itemizedlist>
<para>
Some advanced features of OpenJPA's own <classname>DataSource</classname>
can also be used with third-party implementations. OpenJPA layers on top
of the third-party <classname>DataSource</classname> to provide the
extra functionality. To configure these advanced features, including
prepared statement caching, use the
<link linkend="openjpa.ConnectionFactoryProperties"><literal>openjpa.ConnectionFactoryProperties</literal></link> property
described in the previous section.
</para>
<example id="ref_guide_dbsetup_thirdparty_ex">
<title>Properties File for a Third-Party DataSource</title>
<programlisting format="linespecific">
&lt;property name="openjpa.ConnectionDriverName" value="oracle.jdbc.pool.OracleDataSource"/&gt;
&lt;property name="openjpa.ConnectionProperties"
value="PortNumber=1521, ServerName=saturn, DatabaseName=solarsid, DriverType=thin"/&gt;
&lt;property name="openjpa.ConnectionFactoryProperties" value="QueryTimeout=5000"/&gt;
</programlisting>
</example>
<section id="ref_guide_dbsetup_thirdparty_enlist">
<title>Managed and XA DataSources</title>
<indexterm zone="ref_guide_dbsetup_thirdparty_enlist">
<primary>DataSource</primary>
<secondary>managed</secondary>
</indexterm>
<indexterm zone="ref_guide_dbsetup_thirdparty_enlist">
<primary>DataSource</primary>
<secondary>XA</secondary>
</indexterm>
<para><indexterm><primary>ConnectionFactoryMode</primary></indexterm>
Certain application servers automatically enlist their <classname>
DataSource</classname>s in global transactions. When this is the
case, OpenJPA should not attempt to commit the underlying connection,
leaving JDBC transaction completion to the application server. To
notify OpenJPA that your third-party <classname>DataSource</classname>
is managed by the application server, set the
<link linkend="openjpa.ConnectionFactoryMode"><literal>openjpa.ConnectionFactoryMode</literal></link> property to
<literal>managed</literal>.
</para>
<para>
Note that OpenJPA can only use managed
<classname>DataSource</classname>s when it is also
integrating with the application server's managed transactions.
Also
note that all XA <classname>DataSource</classname>s are enlisted,
and you must set this property when using any XA <classname>
DataSource</classname>.
</para>
<para>
When using a managed <classname>DataSource</classname>, you
should also configure a second unmanaged
<classname>DataSource</classname> that OpenJPA can use to perform
tasks that are independent of the global transaction.
The most common of these tasks is updating the sequence table OpenJPA
uses to generate unique primary key values for your
datastore identity objects. Configure the second <classname>
DataSource</classname> just as the first, but use the various "2"
connection properties, such as
<literal>openjpa.ConnectionFactory2Name</literal>
or <literal>openjpa.Connection2DriverName</literal>.
These properties are outlined in <xref linkend="ref_guide_conf"/>.
<phrase>
If your second <classname>DataSource</classname> is also bound to
JNDI, you can use JPA XML's <literal>non-jta-data-source</literal>
to specify its location.
</phrase>
Typically, <phrase>though,</phrase> you will use
OpenJPA's built-in implementation
for the second <classname>DataSource</classname>
(see <xref linkend="ref_guide_dbsetup_builtin"/>).
</para>
<example id="ref_guide_enterprise_xa_conf_ex">
<title>Managed DataSource Configuration</title>
<programlisting format="linespecific">
&lt;!-- managed DataSource --&gt;
&lt;jta-data-source&gt;java:/OracleXASource&lt;/jta-data-source&gt;
&lt;properties&gt;
&lt;!-- use OpenJPA's built-in DataSource for unmanaged connections --&gt;
&lt;property name="openjpa.Connection2UserName" value="scott"/&gt;
&lt;property name="openjpa.Connection2Password" value="tiger"/&gt;
&lt;property name="openjpa.Connection2URL" value="jdbc:oracle:thin:@CROM:1521:OpenJPADB"/&gt;
&lt;property name="openjpa.Connection2DriverName" value="oracle.jdbc.driver.OracleDriver"/&gt;
&lt;property name="openjpa.ConnectionFactory2Properties" value="MaxActive=20, MaxIdle=10"/&gt;
&lt;!-- managed transaction and enlisted configuration --&gt;
&lt;property name="openjpa.TransactionMode" value="managed"/&gt;
&lt;property name="openjpa.ConnectionFactoryMode" value="managed"/&gt;
&lt;/properties&gt;
</programlisting>
</example>
</section>
</section>
<section id="ref_guide_dbsetup_sqlconn">
<title>Runtime Access to DataSource</title>
<indexterm zone="ref_guide_dbsetup_sqlconn">
<primary>connections</primary>
<secondary>accessing DataSource</secondary>
</indexterm>
<indexterm zone="ref_guide_dbsetup_sqlconn">
<primary>JDBC</primary>
<secondary>accessing DataSource</secondary>
</indexterm>
<para>
The JPA standard defines how to access JDBC connections from enterprise
beans. OpenJPA also provides APIs to access an <classname>
EntityManager</classname>'s connection, or to retrieve a connection
directly from the <classname>EntityManagerFactory</classname>'s
<classname>DataSource</classname>.
</para>
<para>
The <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><methodname>OpenJPAEntityManager.getConnection</methodname></ulink> method
returns an <classname>EntityManager</classname>'s connection. If the
<classname>EntityManager</classname> does not already have a connection,
it will obtain one. The returned connection is only guaranteed to be
transactionally consistent with other <classname>EntityManager
</classname> operations if the <classname>EntityManager</classname> is
in a managed or non-optimistic transaction, if the <classname>
EntityManager</classname> has flushed in the current transaction, or if
you have used the <methodname>OpenJPAEntityManager.beginStore</methodname>
method to ensure that a datastore transaction is in progress. Always
close the returned connection before attempting any other
<classname>EntityManager</classname> operations. OpenJPA will ensure that
the underlying native connection is not released if a datastore
transaction is in progress.
</para>
<example id="ref_guide_dbsetup_conn_ejb">
<title>Using the EntityManager's Connection</title>
<programlisting format="linespecific">
import java.sql.*;
import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
Connection conn = (Connection) kem.getConnection ();
// do JDBC stuff
conn.close ();
</programlisting>
</example>
<para>
The example below shows how to use a connection directly from the
<classname>DataSource</classname>, rather than using an <classname>
EntityManager</classname>'s connection.
</para>
<example id="ref_guide_dbsetup_conn_from_factory_ejb">
<title>Using the EntityManagerFactory's DataSource</title>
<programlisting format="linespecific">
import java.sql.*;
import javax.sql.*;
import org.apache.openjpa.conf.*;
import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
OpenJPAConfiguration conf = kemf.getConfiguration ();
DataSource dataSource = (DataSource) conf.getConnectionFactory ();
Connection conn = dataSource.getConnection ();
// do JDBC stuff
conn.close ();
</programlisting>
</example>
</section>
<section id="ref_guide_dbsetup_dbsupport">
<title>Database Support</title>
<indexterm zone="ref_guide_dbsetup_dbsupport">
<primary>DBDictionary</primary>
</indexterm>
<indexterm zone="ref_guide_dbsetup_dbsupport">
<primary>relational database</primary>
<secondary>OpenJPA support</secondary>
<seealso>DBDictionary</seealso>
</indexterm>
<para>
OpenJPA <phrase>JPA</phrase> can take advantage of any JDBC 2.x compliant
driver, making almost any major database a candidate for use. See
our officially supported database list in
<xref linkend="supported_databases"/> for more information. Typically,
OpenJPA auto-configures its JDBC behavior and SQL dialect for your
database, based on the values of your connection-related configuration
properties.
</para>
<para>
If OpenJPA cannot detect what type of database you are using, or if
you are using an unsupported database, you will have to tell OpenJPA
what <ulink url="../apidocs/org/apache/openjpa/jdbc/sql/DBDictionary.html"><classname>org.apache.openjpa.jdbc.sql.DBDictionary</classname></ulink> to use.
The <classname>DBDictionary</classname> abstracts away the differences
between databases. You can plug a dictionary into OpenJPA using the
<link linkend="openjpa.jdbc.DBDictionary"><literal>openjpa.jdbc.DBDictionary
</literal></link> configuration property. The built-in dictionaries
are listed below. If you are using an unsupported database, you may
have to write your own <classname>DBDictionary</classname> subclass,
a simple process.
</para>
<itemizedlist>
<listitem>
<para><indexterm><primary>Microsoft Access</primary></indexterm><literal>access</literal>: Dictionary for Microsoft
Access. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/AccessDictionary.html"><classname>org.apache.openjpa.jdbc.sql.AccessDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>DB2</primary></indexterm><literal>db2</literal>: Dictionary for IBM's DB2 database.
This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/DB2Dictionary.html"><classname>org.apache.openjpa.jdbc.sql.DB2Dictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Derby</primary></indexterm><literal>derby</literal>: Dictionary for the Apache Derby
database. This is an alias for the
<ulink url="javadoc/openjpa/jdbc/sql/DerbyDictionary.html"><classname>org.apache.openjpa.jdbc.sql.DerbyDictionary</classname> class.
</ulink></para>
</listitem>
<listitem>
<para><indexterm><primary>Empress</primary></indexterm><literal>empress</literal>: Dictionary for Empress database
This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/EmpressDictionary.html"><classname>org.apache.openjpa.jdbc.sql.EmpressDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>FoxPro</primary></indexterm><literal>foxpro</literal>: Dictionary for Microsoft
Visual FoxPro. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/FoxProDictionary.html"><classname>org.apache.openjpa.jdbc.sql.FoxProDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Hypersonic SQL</primary></indexterm><literal>hsql</literal>: Dictionary for the Hypersonic SQL
database. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/HSQLDictionary.html"><classname>org.apache.openjpa.jdbc.sql.HSQLDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Informix</primary></indexterm><literal>informix</literal>: Dictionary for the Informix
database. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/InformixDictionary.html"><classname>org.apache.openjpa.jdbc.sql.InformixDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>JDataStore</primary></indexterm><literal>jdatastore</literal>: Dictionary for Borland
JDataStore. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/JDataStoreDictionary.html"><classname>org.apache.openjpa.jdbc.sql.JDataStoreDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>MySQL</primary></indexterm><literal>mysql</literal>: Dictionary for the MySQL
database. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/MySQLDictionary.html"><classname>org.apache.openjpa.jdbc.sql.MySQLDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Oracle</primary></indexterm><literal>oracle</literal>: Dictionary for Oracle.
This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/OracleDictionary.html"><classname>org.apache.openjpa.jdbc.sql.OracleDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Pointbase</primary></indexterm><literal>pointbase</literal>: Dictionary for Pointbase Embedded
database. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/PointbaseDictionary.html"><classname>org.apache.openjpa.jdbc.sql.PointbaseDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>PostgreSQL</primary></indexterm><literal>postgres</literal>: Dictionary for PostgreSQL.
This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/PostgresDictionary.html"><classname>org.apache.openjpa.jdbc.sql.PostgresDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>SQLServer</primary></indexterm><literal>sqlserver</literal>: Dictionary for Microsoft's
SQLServer database. This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/SQLServerDictionary.html"><classname>org.apache.openjpa.jdbc.sql.SQLServerDictionary</classname></ulink> class.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Sybase</primary></indexterm><literal>sybase</literal>: Dictionary for Sybase.
This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/SybaseDictionary.html"><classname>org.apache.openjpa.jdbc.sql.SybaseDictionary</classname></ulink> class.
</para>
</listitem>
</itemizedlist>
<para>
The example below demonstrates how to set a dictionary and configure
its properties in your configuration file. The <literal>DBDictionary
</literal> property uses OpenJPA's
<link linkend="ref_guide_conf_plugins">plugin syntax</link>.
</para>
<example id="ref_guide_dbsetup_dbdict">
<title>Specifying a DBDictionary</title>
<programlisting format="linespecific">
&lt;property name="openjpa.jdbc.DBDictionary" value="hsql(SimulateLocking=true)"/&gt;
</programlisting>
</example>
<section id="ref_guide_dbsetup_dbdictprops">
<title>DBDictionary Properties</title>
<para>
The standard dictionaries all recognize the following properties.
These properties will usually not need to be overridden, since the
dictionary implementation should use the appropriate default values
for your database. You typically won't use these properties
unless you are designing your own <classname>DBDictionary
</classname> for an unsupported database.
</para>
<itemizedlist>
<listitem id="DBDictionary.DriverVendor">
<para><indexterm><primary>JDBC</primary><secondary>DriverVendor</secondary></indexterm><literal>DriverVendor</literal>: The vendor of the particular
JDBC driver you are using. Some dictionaries must alter their
behavior depending on the driver vendor. See the
<literal>VENDOR_XXX</literal> constants defined in your
dictionary's Javadoc for available options.
</para>
</listitem>
<listitem id="DBDictionary.CatalogSeparator">
<para><indexterm><primary>SQL</primary><secondary>CatalogSeparator</secondary></indexterm><literal>CatalogSeparator</literal>:
The string the database uses to delimit between
the schema name and the table name. This is typically
<literal>"."</literal>, which is the default.
</para>
</listitem>
<listitem id="DBDictionary.CreatePrimaryKeys">
<para><indexterm><primary>DDL</primary><secondary>CreatePrimaryKeys</secondary></indexterm><literal>CreatePrimaryKeys</literal>: If
<literal>false</literal>, then do not create database
primary keys for identifiers. Defaults to
<literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.ConstraintNameMode">
<para><indexterm><primary>DDL</primary><secondary>ConstraintNameMode</secondary></indexterm><literal>ConstraintNameMode</literal>: When
creating constraints, whether to put the constraint name
before the definition (<literal>before</literal>), just after
the constraint type name (<literal>mid</literal>), or after the
constraint definition (<literal>after</literal>).
Defaults to <literal>before</literal>.
</para>
</listitem>
<listitem id="DBDictionary.MaxTableNameLength">
<para><indexterm><primary>DDL</primary><secondary>MaxTableNameLength</secondary></indexterm><literal>MaxTableNameLength</literal>: The maximum number
of characters in a table name. Defaults to 128.
</para>
</listitem>
<listitem id="DBDictionary.MaxColumnNameLength">
<para><indexterm><primary>DDL</primary><secondary>MaxColumnNameLength</secondary></indexterm><literal>MaxColumnNameLength</literal>: The maximum number
of characters in a column name. Defaults to 128.
</para>
</listitem>
<listitem id="DBDictionary.MaxConstraintNameLength">
<para><indexterm><primary>DDL</primary><secondary>MaxConstraintNameLength</secondary></indexterm><literal>MaxConstraintNameLength</literal>: The maximum number
of characters in a constraint name. Defaults to 128.
</para>
</listitem>
<listitem id="DBDictionary.MaxIndexNameLength">
<para><indexterm><primary>DDL</primary><secondary>MaxIndexNameLength</secondary></indexterm><indexterm><primary>indexes</primary><secondary>MaxIndexNameLength</secondary></indexterm><literal>MaxIndexNameLength</literal>: The maximum number
of characters in an index name. Defaults to 128.
</para>
</listitem>
<listitem id="DBDictionary.MaxAutoAssignNameLength">
<para><indexterm><primary>DDL</primary><secondary>MaxAutoAssignNameLength</secondary></indexterm><literal>MaxAutoAssignNameLength</literal>: Set
this property to the maximum length of name for
sequences used for auto-increment columns. Names
longer than this value are truncated.
Defaults to <literal>31</literal>.
</para>
</listitem>
<listitem id="DBDictionary.MaxIndexesPerTable">
<para><indexterm><primary>indexes</primary><secondary>MaxIndexesPerTable</secondary></indexterm><literal>MaxIndexesPerTable</literal>: The maximum number
of indexes that can be placed on a single table. Defaults to
no limit.
</para>
</listitem>
<listitem id="DBDictionary.SupportsForeignKeys">
<para><indexterm><primary>foreign keys</primary><secondary>SupportsForeignKeys</secondary></indexterm><literal>SupportsForeignKeys</literal>: Whether the database
supports foreign keys. Defaults to true.
</para>
</listitem>
<listitem id="DBDictionary.SupportsUniqueConstraints">
<para><indexterm><primary>unique constraints</primary><secondary>SupportsUniqueConstraints</secondary></indexterm><literal>SupportsUniqueConstraints</literal>: Whether the
database supports unique constraints. Defaults to true.
</para>
</listitem>
<listitem id="DBDictionary.SupportsDeferredConstraints">
<para><indexterm><primary>foreign keys</primary><secondary>SupportsDeferredConstraints</secondary></indexterm><literal>SupportsDeferredConstraints</literal>: Whether the
database supports deferred constraints. Defaults to true.
</para>
</listitem>
<listitem id="DBDictionary.SupportsRestrictDeleteAction">
<para><indexterm><primary>foreign keys</primary><secondary>SupportsRestrictDeleteAction</secondary></indexterm><literal>SupportsRestrictDeleteAction</literal>: Whether the
database supports the RESTRICT foreign key delete action.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsCascadeDeleteAction">
<para><indexterm><primary>foreign keys</primary><secondary>SupportsCascadeDeleteAction</secondary></indexterm><literal>SupportsCascadeDeleteAction</literal>: Whether the
database supports the CASCADE foreign key delete action.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsNullDeleteAction">
<para><indexterm><primary>foreign keys</primary><secondary>SupportsNullDeleteAction</secondary></indexterm><literal>SupportsNullDeleteAction</literal>: Whether the
database supports the SET NULL foreign key delete action.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsDefaultDeleteAction">
<para><indexterm><primary>foreign keys</primary><secondary>SupportsDefaultDeleteAction</secondary></indexterm><literal>SupportsDefaultDeleteAction</literal>: Whether the
database supports the SET DEFAULT foreign key delete action.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsAlterTableWithAddColumn">
<para><indexterm><primary>DDL</primary><secondary>SupportsAlterTableWithAddColumn</secondary></indexterm><literal>SupportsAlterTableWithAddColumn</literal>: Whether the
database supports adding a new column in an ALTER TABLE
statement. Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsAlterTableWithDropColumn">
<para><indexterm><primary>DDL</primary><secondary>SupportsAlterTableWithDropColumn</secondary></indexterm><literal>SupportsAlterTableWithDropColumn</literal>: Whether
the database supports dropping a column in an ALTER TABLE
statement. Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.ReservedWords">
<para><indexterm><primary>SQL</primary><secondary>ReservedWords</secondary></indexterm><literal>ReservedWords</literal>: A comma-separated list of
reserved words for this database, beyond the standard SQL92
keywords.
</para>
</listitem>
<listitem id="DBDictionary.SystemTables">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SystemTables</tertiary></indexterm><literal>SystemTables</literal>: A comma-separated list of
table names that should be ignored.
</para>
</listitem>
<listitem id="DBDictionary.SystemSchemas">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SystemSchemas</tertiary></indexterm><literal>SystemSchemas</literal>: A comma-separated list of
schema names that should be ignored.
</para>
</listitem>
<listitem id="DBDictionary.SchemaCase">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SchemaCase</tertiary></indexterm><literal>SchemaCase</literal>: The case to use when querying
the database metadata about schema components. Defaults to
making all names upper case. Available values are:
<literal>upper, lower, preserve</literal>.
</para>
</listitem>
<listitem id="DBDictionary.ValidationSQL">
<para><indexterm><primary>connections</primary><secondary>ValidationSQL</secondary></indexterm><indexterm><primary>SQL</primary><secondary>ValidationSQL</secondary></indexterm><literal>ValidationSQL</literal>: The SQL used to
validate that a connection is still in a valid state. For
example, "<literal>SELECT SYSDATE FROM DUAL</literal>" for
Oracle.
</para>
</listitem>
<listitem id="DBDictionary.InitializationSQL">
<para><indexterm><primary>connections</primary><secondary>InitializationSQL</secondary></indexterm><indexterm><primary>SQL</primary><secondary>InitializationSQL</secondary></indexterm><literal>InitializationSQL</literal>: A piece of SQL to issue
against the database whenever a connection is retrieved from
the <classname>DataSource</classname>.
</para>
</listitem>
<listitem id="DBDictionary.JoinSyntax">
<para><indexterm><primary>joins</primary><secondary>JoinSyntax</secondary></indexterm><literal>JoinSyntax</literal>: The SQL join syntax
to use in select statements. See
<xref linkend="ref_guide_dbsetup_sql92"/>.
</para>
</listitem>
<listitem id="DBDictionary.CrossJoinClause">
<para><indexterm><primary>joins</primary><secondary>CrossJoinClause</secondary></indexterm><literal>CrossJoinClause</literal>: The clause to use for
a cross join (cartesian product).
Defaults to <literal>CROSS JOIN</literal>.
</para>
</listitem>
<listitem id="DBDictionary.InnerJoinClause">
<para><indexterm><primary>joins</primary><secondary>InnerJoinClause</secondary></indexterm><literal>InnerJoinClause</literal>: The clause to use for
an inner join. Defaults to <literal>INNER JOIN</literal>.
</para>
</listitem>
<listitem id="DBDictionary.OuterJoinClause">
<para><indexterm><primary>joins</primary><secondary>OuterJoinClause</secondary></indexterm><literal>OuterJoinClause</literal>: The clause to use for
an left outer join.
Defaults to <literal>LEFT OUTER JOIN</literal>.
</para>
</listitem>
<listitem id="DBDictionary.RequiresConditionForCrossJoin">
<para><indexterm><primary>joins</primary><secondary>RequiresConditionForCrossJoin</secondary></indexterm><literal>RequiresConditionForCrossJoin</literal>: Some
databases require that there always be a conditional
statement for a cross join. If set, this parameter ensures
that there will always be some condition to the join clause.
</para>
</listitem>
<listitem id="DBDictionary.ToUpperCaseFunction">
<para><indexterm><primary>SQL</primary><secondary>ToUpperCaseFunction</secondary></indexterm><literal>ToUpperCaseFunction</literal>: SQL function call for
for converting a string to upper case. Use the token
<literal>{0}</literal> to represent the argument.
</para>
</listitem>
<listitem id="DBDictionary.ToLowerCaseFunction">
<para><indexterm><primary>SQL</primary><secondary>ToLowerCaseFunction</secondary></indexterm><literal>ToLowerCaseFunction</literal>: Name of the SQL function
for converting a string to lower case. Use the token
<literal>{0}</literal> to represent the argument.
</para>
</listitem>
<listitem id="DBDictionary.StringLengthFunction">
<para><indexterm><primary>SQL</primary><secondary>StringLengthFunction</secondary></indexterm><literal>StringLengthFunction</literal>: Name of the SQL
function for getting the length of a string. Use the token
<literal>{0}</literal> to represent the argument.
</para>
</listitem>
<listitem id="DBDictionary.SubstringFunctionName">
<para><indexterm><primary>SQL</primary><secondary>SubstringFunctionName</secondary></indexterm><literal>SubstringFunctionName</literal>: Name of the SQL
function for getting the substring of a string.
</para>
</listitem>
<listitem id="DBDictionary.DistinctCountColumnSeparator">
<para><indexterm><primary>SQL</primary><secondary>DistinctCountColumnSeparator</secondary></indexterm><literal>DistinctCountColumnSeparator</literal>:
The string the database uses to delimit between column
expressions in a <literal>SELECT COUNT(DISTINCT column-list)
</literal> clause. Defaults to null for most databases,
meaning that multiple columns in a distinct COUNT clause are
not supported.
</para>
</listitem>
<listitem id="DBDictionary.ForUpdateClause">
<para><indexterm><primary>SQL</primary><secondary>ForUpdateClause</secondary></indexterm><indexterm><primary>locking</primary><secondary>ForUpdateClause</secondary></indexterm><literal>ForUpdateClause</literal>: The clause to append to
<literal>SELECT</literal> statements to issue queries that
obtain pessimistic locks. Defaults to
<literal>FOR UPDATE</literal>.
</para>
</listitem>
<listitem id="DBDictionary.TableForUpdateClause">
<para><indexterm><primary>SQL</primary><secondary>TableForUpdateClause</secondary></indexterm><indexterm><primary>locking</primary><secondary>TableForUpdateClause</secondary></indexterm><literal>TableForUpdateClause</literal>: The clause to append
to the end of each table alias in queries that obtain
pessimistic locks. Defaults to null.
</para>
</listitem>
<listitem id="DBDictionary.SupportsSelectForUpdate">
<para><indexterm><primary>locking</primary><secondary>SupportsSelectForUpdate</secondary></indexterm><literal>SupportsSelectForUpdate</literal>: If true, then the
database supports <literal>SELECT</literal> statements with a
pessimistic locking clause. Defaults to true.
</para>
</listitem>
<listitem id="DBDictionary.SupportsLockingWithDistinctClause">
<para><indexterm><primary>locking</primary><secondary>SupportsLockingWithDistinctClause</secondary></indexterm><literal>SupportsLockingWithDistinctClause</literal>: If true,
then the database supports <literal>FOR UPDATE</literal>
select clauses with <literal>DISTINCT</literal> clauses.
</para>
</listitem>
<listitem id="DBDictionary.SupportsLockingWithOuterJoin">
<para><indexterm><primary>locking</primary><secondary>SupportsLockingWithOuterJoin</secondary></indexterm><literal>SupportsLockingWithOuterJoin</literal>: If true, then
the database supports <literal>FOR UPDATE</literal> select
clauses with outer join queries.
</para>
</listitem>
<listitem id="DBDictionary.SupportsLockingWithInnerJoin">
<para><indexterm><primary>locking</primary><secondary>SupportsLockingWithInnerJoin</secondary></indexterm><literal>SupportsLockingWithInnerJoin</literal>: If true, then
the database supports <literal>FOR UPDATE</literal> select
clauses with inner join queries.
</para>
</listitem>
<listitem id="DBDictionary.SupportsLockingWithMultipleTables">
<para><indexterm><primary>locking</primary><secondary>SupportsLockingWithMultipleTables</secondary></indexterm><literal>SupportsLockingWithMultipleTables</literal>: If true,
then the database supports <literal>FOR UPDATE</literal> select
clauses that select from multiple tables.
</para>
</listitem>
<listitem id="DBDictionary.SupportsLockingWithOrderClause">
<para><indexterm><primary>locking</primary><secondary>SupportsLockingWithOrderClause</secondary></indexterm><literal>SupportsLockingWithOrderClause</literal>: If true,
then the database supports <literal>FOR UPDATE</literal>
select clauses with <literal>ORDER BY</literal> clauses.
</para>
</listitem>
<listitem id="DBDictionary.SupportsLockingWithSelectRange">
<para><indexterm><primary>locking</primary><secondary>SupportsLockingWithSelectRange</secondary></indexterm><literal>SupportsLockingWithSelectRange</literal>: If true,
then the database supports <literal>FOR UPDATE</literal>
select clauses with queries that select a range of data using
<literal>LIMIT</literal>, <literal>TOP</literal> or the
database equivalent. Defaults to true.
</para>
</listitem>
<listitem id="DBDictionary.SimulateLocking">
<para><indexterm><primary>locking</primary><secondary>SimulateLocking</secondary></indexterm><literal>SimulateLocking</literal>: Some databases
do not support pessimistic locking, which will result in
an exception when you attempt a pessimistic
transaction. Setting this property to
<literal>true</literal> bypasses the locking check to
allow pessimistic transactions even on databases that
do not support locking. Defaults to <literal>false</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsQueryTimeout">
<para><indexterm><primary>JDBC</primary><secondary>QueryTimeout</secondary><tertiary>SupportsQueryTimeout</tertiary></indexterm><literal>SupportsQueryTimeout</literal>: If true, then the
JDBC driver supports calls to <methodname>
java.sql.Statement.setQueryTimeout</methodname>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsHaving">
<para><indexterm><primary>aggregates</primary><secondary>having</secondary><tertiary>SupportsHaving</tertiary></indexterm><literal>SupportsHaving</literal>: Whether this database
supports HAVING clauses in selects.
</para>
</listitem>
<listitem id="DBDictionary.SupportsSelectStartIndex">
<para><indexterm><primary>Query</primary><secondary>result range</secondary><tertiary>SupportsSelectStartIndex</tertiary></indexterm><literal>SupportsSelectStartIndex</literal>: Whether this
database can create a select that skips the first N results.
</para>
</listitem>
<listitem id="DBDictionary.SupportsSelectEndIndex">
<para><indexterm><primary>Query</primary><secondary>result range</secondary><tertiary>SupportsSelectEndIndex</tertiary></indexterm><literal>SupportsSelectEndIndex</literal>: Whether this
database can create a select that is limited to the first N
results.
</para>
</listitem>
<listitem id="DBDictionary.SupportsSubselect">
<para><indexterm><primary>SQL</primary><secondary>SupportsSubselect</secondary></indexterm><indexterm><primary>JPQL</primary><secondary>subselects</secondary><tertiary>SupportsSubselect</tertiary></indexterm><literal>SupportsSubselect</literal>: Whether this database
supports subselects in queries.
</para>
</listitem>
<listitem id="DBDictionary.RequiresAliasForSubselect">
<para><indexterm><primary>SQL</primary><secondary>RequiresAliasForSubselect</secondary></indexterm><indexterm><primary>JPQL</primary><secondary>subselects</secondary><tertiary>RequiresAliasForSubselect</tertiary></indexterm><literal>RequiresAliasForSubselect</literal>: If true, then
the database requires that subselects in a FROM clause be
assigned an alias.
</para>
</listitem>
<listitem id="DBDictionary.SupportsMultipleNontransactionalResultSets">
<para><literal>SupportsMultipleNontransactionalResultSets</literal>:
If true, then a nontransactional connection is capable
of having multiple open <classname>ResultSet</classname>
instances.
</para>
</listitem>
<listitem id="DBDictionary.StorageLimitationsFatal">
<para><indexterm><primary>persistent fields</primary><secondary>StorageLimitationsFatal</secondary></indexterm><literal>StorageLimitationsFatal</literal>: If true, then any
data truncation/rounding that is performed by the dictionary
in order to store a value in the database will be treated as
a fatal error, rather than just issuing a warning.
</para>
</listitem>
<listitem id="DBDictionary.StoreLargeNumbersAsStrings">
<para><indexterm><primary>persistent fields</primary><secondary>StoreLargeNumbersAsStrings</secondary></indexterm><literal>StoreLargeNumbersAsStrings</literal>: Many
databases have limitations on the number of digits that can
be stored in a numeric field (for example, Oracle can only
store 38 digits). For applications that operate
on very large <classname>BigInteger</classname> and
<classname>BigDecimal</classname> values, it may be
necessary to store these objects as string fields rather
than the database's numeric type. Note that this may
prevent meaningful numeric queries from being executed
against the database. Defaults to
<literal>false</literal>.
</para>
</listitem>
<listitem id="DBDictionary.StoreCharsAsNumbers">
<para><indexterm><primary>persistent fields</primary><secondary>StoreCharsAsNumbers</secondary></indexterm><literal>StoreCharsAsNumbers</literal>: Set this property
to <literal>false</literal> to store Java
<literal>char</literal> fields as <literal>CHAR</literal>
values rather than numbers. Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.UseGetBytesForBlobs">
<para><indexterm><primary>BLOB</primary><secondary>UseGetBytesForBlobs</secondary></indexterm><literal>UseGetBytesForBlobs</literal>: If true, then
<methodname>ResultSet.getBytes</methodname> will be used to
obtain blob data rather than
<methodname>ResultSet.getBinaryStream</methodname>.
</para>
</listitem>
<listitem id="DBDictionary.UseGetObjectForBlobs">
<para><indexterm><primary>BLOB</primary><secondary>UseGetObjectForBlobs</secondary></indexterm><literal>UseGetObjectForBlobs</literal>: If true, then
<methodname>ResultSet.getObject</methodname> will be used to
obtain blob data rather than
<methodname>ResultSet.getBinaryStream</methodname>.
</para>
</listitem>
<listitem id="DBDictionary.UseSetBytesForBlobs">
<para><indexterm><primary>BLOB</primary><secondary>UseSetBytesForBlobs</secondary></indexterm><literal>UseSetBytesForBlobs</literal>: If true, then
<methodname>PreparedStatement.setBytes</methodname>
will be used to set blob data, rather than
<methodname>PreparedStatement.setBinaryStream</methodname>.
</para>
</listitem>
<listitem id="DBDictionary.UseGetStringForClobs">
<para><indexterm><primary>CLOB</primary><secondary>UseGetStringForClobs</secondary></indexterm><literal>UseGetStringForClobs</literal>: If true, then
<methodname>ResultSet.getString</methodname> will be used to
obtain clob data rather than
<methodname>ResultSet.getCharacterStream</methodname>.
</para>
</listitem>
<listitem id="DBDictionary.UseSetStringForClobs">
<para><indexterm><primary>CLOB</primary><secondary>UseSetStringForClobs</secondary></indexterm><literal>UseSetStringForClobs</literal>: If true, then
<methodname>PreparedStatement.setString</methodname>
will be used to set clob data, rather than
<methodname>PreparedStatement.setCharacterStream</methodname>.
</para>
</listitem>
<listitem id="DBDictionary.CharacterColumnSize">
<para><indexterm><primary>DDL</primary><secondary>CharacterColumnSize</secondary></indexterm><literal>CharacterColumnSize</literal>: The default size of
<literal>varchar</literal> and <literal>char</literal> columns.
Typically 255.
</para>
</listitem>
<listitem id="DBDictionary.ArrayTypeName">
<para><indexterm><primary>DDL</primary><secondary>ArrayTypeName</secondary></indexterm><literal>ArrayTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.ARRAY</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.BigintTypeName">
<para><indexterm><primary>DDL</primary><secondary>BigintTypeName</secondary></indexterm><literal>BigintTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.BIGINT</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.BinaryTypeName">
<para><indexterm><primary>DDL</primary><secondary>BinaryTypeName</secondary></indexterm><literal>BinaryTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.BINARY</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.BitTypeName">
<para><indexterm><primary>DDL</primary><secondary>BitTypeName</secondary></indexterm><literal>BitTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.BIT</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.BlobTypeName">
<para><indexterm><primary>DDL</primary><secondary>BlobTypeName</secondary></indexterm><indexterm><primary>BLOB</primary><secondary>BlobTypeName</secondary></indexterm><literal>BlobTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.BLOB</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.CharTypeName">
<para><indexterm><primary>DDL</primary><secondary>CharTypeName</secondary></indexterm><literal>CharTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.CHAR</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.ClobTypeName">
<para><indexterm><primary>DDL</primary><secondary>ClobTypeName</secondary></indexterm><indexterm><primary>CLOB</primary><secondary>ClobTypeName</secondary></indexterm><literal>ClobTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.CLOB</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.DateTypeName">
<para><indexterm><primary>DDL</primary><secondary>DateTypeName</secondary></indexterm><literal>DateTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.DATE</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.DecimalTypeName">
<para><indexterm><primary>DDL</primary><secondary>DecimalTypeName</secondary></indexterm><literal>DecimalTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.DECIMAL</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.DistinctTypeName">
<para><indexterm><primary>DDL</primary><secondary>DistinctTypeName</secondary></indexterm><literal>DistinctTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.DISTINCT</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.DoubleTypeName">
<para><indexterm><primary>DDL</primary><secondary>DoubleTypeName</secondary></indexterm><literal>DoubleTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.DOUBLE</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.FloatTypeName">
<para><indexterm><primary>DDL</primary><secondary>FloatTypeName</secondary></indexterm><literal>FloatTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.FLOAT</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.IntegerTypeName">
<para><indexterm><primary>DDL</primary><secondary>IntegerTypeName</secondary></indexterm><literal>IntegerTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.INTEGER</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.JavaObjectTypeName">
<para><indexterm><primary>DDL</primary><secondary>JavaObjectTypeName</secondary></indexterm><literal>JavaObjectTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.JAVAOBJECT</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.LongVarbinaryTypeName">
<para><indexterm><primary>DDL</primary><secondary>LongVarbinaryTypeName</secondary></indexterm><literal>LongVarbinaryTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.LONGVARBINARY</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.LongVarcharTypeName">
<para><indexterm><primary>DDL</primary><secondary>LongVarcharTypeName</secondary></indexterm><literal>LongVarcharTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.LONGVARCHAR</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.NullTypeName">
<para><indexterm><primary>DDL</primary><secondary>NullTypeName</secondary></indexterm><literal>NullTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.NULL</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.NumericTypeName">
<para><indexterm><primary>DDL</primary><secondary>NumericTypeName</secondary></indexterm><literal>NumericTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.NUMERIC</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.OtherTypeName">
<para><indexterm><primary>DDL</primary><secondary>OtherTypeName</secondary></indexterm><literal>OtherTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.OTHER</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.RealTypeName">
<para><indexterm><primary>DDL</primary><secondary>RealTypeName</secondary></indexterm><literal>RealTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.REAL</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.RefTypeName">
<para><indexterm><primary>DDL</primary><secondary>RefTypeName</secondary></indexterm><literal>RefTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.REF</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SmallintTypeName">
<para><indexterm><primary>DDL</primary><secondary>SmallintTypeName</secondary></indexterm><literal>SmallintTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.SMALLINT</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.StructTypeName">
<para><indexterm><primary>DDL</primary><secondary>StructTypeName</secondary></indexterm><literal>StructTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.STRUCT</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.TimeTypeName">
<para><indexterm><primary>DDL</primary><secondary>TimeTypeName</secondary></indexterm><literal>TimeTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.TIME</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.TimestampTypeName">
<para><indexterm><primary>DDL</primary><secondary>TimestampTypeName</secondary></indexterm><literal>TimestampTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.TIMESTAMP</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.TinyintTypeName">
<para><indexterm><primary>DDL</primary><secondary>TinyintTypeName</secondary></indexterm><literal>TinyintTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.TINYINT</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.VarbinaryTypeName">
<para><indexterm><primary>DDL</primary><secondary>VarbinaryTypeName</secondary></indexterm><literal>VarbinaryTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.VARBINARY</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.VarcharTypeName">
<para><indexterm><primary>DDL</primary><secondary>VarcharTypeName</secondary></indexterm><literal>VarcharTypeName</literal>: The overridden default
column type for <literal>java.sql.Types.VARCHAR</literal>.
This is only used when the schema is generated by
the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.UseSchemaName">
<para><indexterm><primary>schema</primary><secondary>UseSchemaName</secondary></indexterm><literal>UseSchemaName</literal>: If <literal>false</literal>,
then avoid including the schema name in table name references.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.TableTypes">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>TableTypes</tertiary></indexterm><literal>TableTypes</literal>: Comma-separated list of table
types to use when looking for tables during schema reflection,
as defined in the
<methodname>java.sql.DatabaseMetaData.getTableInfo</methodname>
JDBC method. An example is:
<literal>"TABLE,VIEW,ALIAS"</literal>. Defaults to
<literal>"TABLE"</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsSchemaForGetTables">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SupportsSchemaForGetTables</tertiary></indexterm><literal>SupportsSchemaForGetTables</literal>: If false, then
the database driver does not support using
the schema name for schema reflection on table names.
</para>
</listitem>
<listitem id="DBDictionary.SupportsSchemaForGetColumns">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SupportsSchemaForGetColumns</tertiary></indexterm><literal>SupportsSchemaForGetColumns</literal>: If false, then
the database driver does not support using
the schema name for schema reflection on column names.
</para>
</listitem>
<listitem id="DBDictionary.SupportsNullTableForGetColumns">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SupportsNullTableForGetColumns</tertiary></indexterm><literal>SupportsNullTableForGetColumns</literal>:
If true, then the database supports passing a
<literal>null</literal> parameter to
<methodname>DatabaseMetaData.getColumns</methodname>
as an optimization to get information about all the tables.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsNullTableForGetPrimaryKeys">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SupportsNullTableForGetPrimaryKeys</tertiary></indexterm><literal>SupportsNullTableForGetPrimaryKeys</literal>:
If true, then the database supports passing a
<literal>null</literal> parameter to
<methodname>DatabaseMetaData.getPrimaryKeys</methodname>
as an optimization to get information about all the tables.
Defaults to <literal>false</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsNullTableForGetIndexInfo">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SupportsNullTableForGetIndexInfo</tertiary></indexterm><literal>SupportsNullTableForGetIndexInfo</literal>:
If true, then the database supports passing a
<literal>null</literal> parameter to
<methodname>DatabaseMetaData.getIndexInfo</methodname>
as an optimization to get information about all the tables.
Defaults to <literal>false</literal>.
</para>
</listitem>
<listitem id="DBDictionary.SupportsNullTableForGetImportedKeys">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>SupportsNullTableForGetImportedKeys</tertiary></indexterm><literal>SupportsNullTableForGetImportedKeys</literal>:
If true, then the database supports passing a
<literal>null</literal> parameter to
<methodname>DatabaseMetaData.getImportedKeys</methodname>
as an optimization to get information about all the tables.
Defaults to <literal>false</literal>.
</para>
</listitem>
<listitem id="DBDictionary.UseGetBestRowIdentifierForPrimaryKeys">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>UseGetBestRowIdentifierForPrimaryKeys</tertiary></indexterm><literal>UseGetBestRowIdentifierForPrimaryKeys</literal>:
If true, then metadata queries will use
<methodname>DatabaseMetaData.getBestRowIdentifier</methodname>
to obtain information about primary keys, rather than
<methodname>DatabaseMetaData.getPrimaryKeys</methodname>.
</para>
</listitem>
<listitem id="DBDictionary.RequiresAutoCommitForMetadata">
<para><indexterm><primary>schema</primary><secondary>reflection</secondary><tertiary>RequiresAutoCommitForMetaData</tertiary></indexterm><literal>RequiresAutoCommitForMetadata</literal>:
If true, then the JDBC driver requires that autocommit
be enabled before any schema interrogation operations can
take place.
</para>
</listitem>
<listitem id="DBDictionary.AutoAssignClause">
<para><indexterm><primary>persistent fields</primary><secondary>automatic field values</secondary><tertiary>AutoAssignClause</tertiary></indexterm><literal>AutoAssignClause</literal>: The column definition
clause to append to a creation statement. For example,
"<literal>AUTO_INCREMENT</literal>" for MySQL. This property
is set automatically in the dictionary, and should not need to
be overridden, and is only used when the schema is generated
using the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.AutoAssignTypeName">
<para><indexterm><primary>DDL</primary><secondary>AutoAssignTypeName</secondary></indexterm><indexterm><primary>persistent fields</primary><secondary>automatic field values</secondary><tertiary>AutoAssignTypeName</tertiary></indexterm><literal>AutoAssignTypeName</literal>: The column type name
for auto-increment columns. For example,
"<literal>SERIAL</literal>" for PostgreSQL. This property is
set automatically in the dictionary, and should not need to be
overridden, and is only used when the schema is generated
using the <literal>mappingtool</literal>.
</para>
</listitem>
<listitem id="DBDictionary.LastGeneratedKeyQuery">
<para><indexterm><primary>persistent fields</primary><secondary>automatic field values</secondary><tertiary>LastGeneratedKeyQuery</tertiary></indexterm><literal>LastGeneratedKeyQuery</literal>: The query to issue
to obtain the last automatically generated key for an
auto-increment column. For example,
"<literal>select @@identity</literal>" for Sybase.
This property is set automatically in the
dictionary, and should not need to be overridden.
</para>
</listitem>
<listitem id="DBDictionary.NextSequenceQuery">
<para><indexterm><primary>Sequence</primary><secondary>NextSequenceQuery</secondary></indexterm><literal>NextSequenceQuery</literal>: A SQL string for
obtaining a native sequence value. May use a placeholder of
<literal>{0}</literal> for the variable sequence name. Defaults
to a database-appropriate value.
</para>
</listitem>
</itemizedlist>
</section>
<section id="ref_guide_dbsetup_dbsupport_mysql">
<title>MySQLDictionary Properties</title>
<indexterm zone="ref_guide_dbsetup_dbsupport_mysql">
<primary>MySQL</primary>
<seealso>DBDictionary</seealso>
</indexterm>
<para>
The <literal>mysql</literal> dictionary also understands the
following properties:
</para>
<itemizedlist>
<listitem id="MySQLDictionary.DriverDeserializesBlobs">
<para><indexterm><primary>MySQL</primary><secondary>DriverDeserializesBlobs</secondary></indexterm><literal>DriverDeserializesBlobs</literal>: Many MySQL
drivers automatically deserialize BLOBs on calls to
<methodname>ResultSet.getObject</methodname>.
The <classname>MySQLDictionary</classname> overrides the
standard <methodname>DBDictionary.getBlobObject</methodname>
method to take this into account. If your driver does not
deserialize automatically, set this property to
<literal>false</literal>.
</para>
</listitem>
<listitem id="MySQLDictionary.TableType">
<para><indexterm><primary>MySQL</primary><secondary>TableType</secondary></indexterm><literal>TableType</literal>: The MySQL table type to
use when creating tables. Defaults to
<literal>innodb</literal>.
</para>
</listitem>
<listitem id="MySQLDictionary.UseClobs">
<para><indexterm><primary>MySQL</primary><secondary>UseClobs</secondary></indexterm><literal>UseClobs</literal>: Some older versions of
MySQL do not handle clobs correctly. To enable clob
functionality, set this to true. Defaults to
<literal>false</literal>.
</para>
</listitem>
</itemizedlist>
</section>
<section id="ref_guide_dbsetup_dbsupport_oracle">
<title>OracleDictionary Properties</title>
<indexterm zone="ref_guide_dbsetup_dbsupport_oracle">
<primary>Oracle</primary>
<seealso>DBDictionary</seealso>
</indexterm>
<para>
The <literal>oracle</literal> dictionary understands the
following additional properties:
</para>
<itemizedlist>
<listitem id="OracleDictionary.UseTriggersForAutoAssign">
<para><indexterm><primary>Oracle</primary><secondary>UseTriggersForAutoAssign</secondary></indexterm><indexterm><primary>persistent fields</primary><secondary>automatic field values</secondary><tertiary>UseTriggersForAutoAssign</tertiary></indexterm><literal>UseTriggersForAutoAssign</literal>:
If true, then OpenJPA will allow simulation of auto-increment
columns by the use of Oracle triggers. OpenJPA will
assume that the current sequence value from the sequence
specified in the
<literal>AutoAssignSequenceName</literal> parameter
will hold the value of the new primary key for rows that
have been inserted.
For more details on auto-increment support, see
<xref linkend="ref_guide_pc_oid_pkgen_autoinc"/>.
</para>
</listitem>
<listitem id="OracleDictionary.AutoAssignSequenceName">
<para><indexterm><primary>Oracle</primary><secondary>AutoAssignSequenceName</secondary></indexterm><indexterm><primary>persistent fields</primary><secondary>automatic field values</secondary><tertiary>AutoAssignSequenceName</tertiary></indexterm><literal>AutoAssignSequenceName</literal>:
The global name of the sequence that OpenJPA will
assume to hold the value of primary key value
for rows that use auto-increment. If left unset, OpenJPA will
use a the sequence named
<literal>"SEQ_&lt;table name&gt;"</literal>.
</para>
</listitem>
<listitem id="OracleDictionary.MaxEmbeddedBlobSize">
<para><indexterm><primary>Oracle</primary><secondary>MaxEmbeddedBlobSize</secondary></indexterm><indexterm><primary>BLOB</primary><secondary>MaxEmbeddedBlobSize</secondary></indexterm><literal>MaxEmbeddedBlobSize</literal>:
Oracle is unable to persist BLOBs using the embedded update
method when BLOBs get over a certain size. The size depends
on database configuration, e.g. encoding. This property
defines the maximum size BLOB to persist with the embedded
method. Defaults to 4000 bytes.
</para>
</listitem>
<listitem id="OracleDictionary.MaxEmbeddedClobSize">
<para><indexterm><primary>Oracle</primary><secondary>MaxEmbeddedClobSize</secondary></indexterm><indexterm><primary>CLOB</primary><secondary>MaxEmbeddedClobSize</secondary></indexterm><literal>MaxEmbeddedClobSize</literal>:
Oracle is unable to persist CLOBs using the embedded update
method when Clobs get over a certain size. The size depends
on database configuration, e.g. encoding. This property
defines the maximum size CLOB to persist with the embedded
method. Defaults to 4000 characters.
</para>
</listitem>
<listitem id="OracleDictionary.UseSetFormOfUseForUnicode">
<para><literal>UseSetFormOfUseForUnicode</literal>:
Prior to Oracle 10i, statements executed against
unicode capable columns (the <literal>NCHAR</literal>,
<literal>NVARCHAR</literal>, <literal>NCLOB</literal>
Oracle types) required special handling to be able to
store unicode values. Setting this property
to true (the default) will cause OpenJPA to attempt
to detect when the column of one of these types, and
if so, will attempt to correctly configure the
statement using the <methodname>
OraclePreparedStatement.setFormOfUse</methodname>.
For more details, see the Oracle
<ulink url="http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/nchar/readme.html">
Readme For NChar</ulink>.
Note that this can only work if OpenJPA is able to
access the underlying
<classname>OraclePreparedStatement</classname> instance,
which may not be possible when using some third-party
datasources. If OpenJPA detects that this is the case,
a warning will be logged.
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="ref_guide_dbsetup_sqlfactory">
<title>SQLFactory Properties</title>
<indexterm zone="ref_guide_dbsetup_dbsupport">
<primary>SQL</primary>
<secondary>SQLFactory</secondary>
</indexterm>
<para>
Some aspects of advanced SQL aren't configured through the
<classname>DBDictionary</classname>, but through the
<classname>SQLFactory</classname>. The
<literal>openjpa.jdbc.SQLFactory</literal> configuration property is
a <link linkend="ref_guide_conf_plugins">plugin string</link>
you can use to configure the following parameters:
</para>
<itemizedlist>
<listitem id="SQLFactory.BatchLimit">
<para><indexterm><primary>prepared statement</primary><secondary>batching</secondary><tertiary>BatchLimit</tertiary></indexterm><literal>BatchLimit</literal>: The maximum number of SQL
update statements to batch together. Set to 0 to disable
statement batching, or -1 for no limit. See
<xref linkend="ref_guide_perfpack_batch"/>.
</para>
</listitem>
<listitem id="SQLFactory.BatchParameterLimit">
<para><indexterm><primary>prepared statement</primary><secondary>batching</secondary><tertiary>BatchParameterLimit</tertiary></indexterm><literal>BatchParameterLimit</literal>: The maximum number of
parameters that can be batched together for a single
batch update. Some databases can only handle a certain
total number of prepared statement parameters in a single
batch. This value will cause OpenJPA to flush a SQL batch
once the number of batched statements times the number of
bound parameters per statement exceeds this value.
Set to 0 to disable SQL batching, or -1 for no limit.
</para>
</listitem>
<listitem id="SQLFactory.SupportsUpdateCountsForBatch">
<para><indexterm><primary>prepared statement</primary><secondary>batching</secondary><tertiary>SupportsUpdateCountsForBatch</tertiary></indexterm><literal>SupportsUpdateCountsForBatch</literal>: Whether the
JDBC driver correctly returns the set of update counts when
a batch statement is executed.
</para>
</listitem>
<listitem id="SQLFactory.SupportsTotalCountsForBatch">
<para><indexterm><primary>prepared statement</primary><secondary>batching</secondary><tertiary>SupportsTotalCountsForBatch</tertiary></indexterm><literal>SupportsTotalCountsForBatch</literal>: If a JDBC
driver doesn't support batch update counts, whether it
at least returns the total number of updates made when a batch
statement is executed.
</para>
</listitem>
<listitem id="SQLFactory.SupportsUnion">
<para><indexterm><primary>SQL</primary><secondary>union</secondary><tertiary>SupportsUnion</tertiary></indexterm><literal>SupportsUnion</literal>: Whether the database supports
SQL UNIONs.
</para>
</listitem>
<listitem id="SQLFactory.SupportsUnionWithUnalignedOrdering">
<para><indexterm><primary>SQL</primary><secondary>union</secondary><tertiary>SupportsUnionWithUnalignedOrdering</tertiary></indexterm><literal>SupportsUnionWithUnalignedOrdering</literal>: Whether
the database supports SQL UNIONs that order on columns that are
not in the same position in all the SELECTs that make up the
UNION.
</para>
</listitem>
</itemizedlist>
<para>
The defaults for these properties depend on the database in use.
</para>
<example id="ref_guide_dbsetup_sqlfactoryex">
<title>Configuring SQLFactory Properties</title>
<programlisting format="linespecific">
&lt;property name="openjpa.jdbc.SQLFactory" value="BatchLimit=100, SupportsUnion=true"/&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_dbsetup_isolation">
<title>Setting the Transaction Isolation</title>
<indexterm zone="ref_guide_dbsetup_isolation">
<primary>transactions</primary>
<secondary>isolation</secondary>
</indexterm>
<indexterm zone="ref_guide_dbsetup_isolation">
<primary>JDBC</primary>
<secondary>transaction isolation</secondary>
</indexterm>
<indexterm>
<primary>TransactionIsolation</primary>
</indexterm>
<para>
OpenJPA typically retains the default transaction isolation level
of the JDBC driver. However, you can specify a transaction isolation
level to use through the <link linkend="openjpa.jdbc.TransactionIsolation"><literal>openjpa.jdbc.TransactionIsolation</literal></link> configuration
property. The following is a list of standard isolation levels.
Note that not all databases support all isolation levels.
</para>
<itemizedlist>
<listitem>
<para><literal>default</literal>: Use the JDBC driver's default
isolation level. OpenJPA uses this option if you do not
explicitly specify any other.
</para>
</listitem>
<listitem>
<para><literal>none</literal>: No transaction isolation.
</para>
</listitem>
<listitem>
<para><literal>read-committed</literal>: Dirty reads are
prevented; non-repeatable reads and phantom reads can
occur.
</para>
</listitem>
<listitem>
<para><literal>read-uncommitted</literal>: Dirty reads,
non-repeatable reads and phantom reads can occur.
</para>
</listitem>
<listitem>
<para><literal>repeatable-read</literal>: Dirty reads and
non-repeatable reads are prevented; phantom reads can occur.
</para>
</listitem>
<listitem>
<para><literal>serializable</literal>: Dirty reads,
non-repeatable reads, and phantom reads are prevented.
</para>
</listitem>
</itemizedlist>
<example id="ref_guide_dbsetup_isoex">
<title>Specifying a Transaction Isolation</title>
<programlisting format="linespecific">
&lt;property name="openjpa.jdbc.TransactionIsolation" value="repeatable-read"/&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_dbsetup_sql92">
<title>Setting the SQL Join Syntax</title>
<indexterm zone="ref_guide_dbsetup_sql92">
<primary>joins</primary>
<secondary>syntax options</secondary>
</indexterm>
<indexterm zone="ref_guide_dbsetup_sql92">
<primary>SQL</primary>
<secondary>join syntax</secondary>
</indexterm>
<para>
Object queries often involve using SQL joins behind the scenes. You can
configure OpenJPA to use either SQL 92-style join syntax, in which joins
are placed in the SQL FROM clause, the traditional join syntax, in
which join criteria are part of the WHERE clause, or a database-specific
join syntax mandated by the <link linkend="ref_guide_dbsetup_dbdict"><classname>DBDictionary</classname></link>. OpenJPA only supports outer
joins when using SQL 92 syntax or a database-specific syntax with outer
join support.
</para>
<para>
The <link linkend="openjpa.jdbc.DBDictionary"><literal>
openjpa.jdbc.DBDictionary</literal></link> plugin accepts the
the <literal>JoinSyntax</literal> property to set
the system's default syntax. The available values are:
</para>
<itemizedlist>
<listitem>
<para><literal>traditional</literal>: Traditional SQL
join syntax; outer joins are not supported.
</para>
</listitem>
<listitem>
<para><literal>database</literal>: The database's native
join syntax. Databases that do not have a native
syntax will default to one of the other options.
</para>
</listitem>
<listitem>
<para><literal>sql92</literal>: ANSI SQL92 join syntax.
Outer joins are supported. Not all databases
support this syntax.
</para>
</listitem>
</itemizedlist>
<para>
You can change the join syntax at runtime through the OpenJPA
fetch configuration API, which is described in
<xref linkend="ref_guide_runtime"/>.
</para>
<example id="ref_guide_dbsetup_sql92_conf">
<title>Specifying the Join Syntax Default</title>
<programlisting format="linespecific">
&lt;property name="openjpa.jdbc.DBDictionary" value="JoinSyntax=sql92"/&gt;
</programlisting>
</example>
<example id="ref_guide_dbsetup_sql92_fetch">
<title>Specifying the Join Syntax at Runtime</title>
<programlisting format="linespecific">
import org.apache.openjpa.persistence.jdbc.*;
...
Query q = em.createQuery ("select m from Magazine m where m.title = 'JDJ'");
OpenJPAQuery kq = OpenJPAPersistence.cast (q);
JDBCFetchPlan fetch = (JDBCFetchPlan) kq.getFetchPlan ();
fetch.setJoinSyntax (JDBCFetchPlan.JOIN_SYNTAX_SQL92);
List results = q.getResultList ();
</programlisting>
</example>
</section>
<section id="ref_guide_dbsetup_multidb">
<title>Accessing Multiple Databases</title>
<indexterm zone="ref_guide_dbsetup_multidb">
<primary>relational database</primary>
<secondary>accessing multiple databases</secondary>
</indexterm>
<para>
Through the properties we've covered thus far, you can configure each
<phrase><classname>EntityManagerFactory</classname></phrase>
to access a different database. If your application accesses multiple
databases, we recommend that you maintain a separate properties file
for each one. This will allow you to easily load the appropriate
resource for each database at runtime, and to give the correct
configuration file to OpenJPA's command-line tools during development.
</para>
</section>
<section id="ref_guide_dbsetup_retain">
<title>Configuring the Use of JDBC Connections</title>
<indexterm zone="ref_guide_dbsetup_retain">
<primary>connections</primary>
<secondary>usage</secondary>
</indexterm>
<para>
In its default configuration, OpenJPA obtains JDBC connections on
an as-needed basis. OpenJPA <classname>EntityManager</classname>s do
not retain a connection to the database unless they are in a datastore
transaction or there are open <classname>Query</classname> results that
are using a live JDBC result set. At all other times, including
during optimistic transactions, <classname>EntityManager</classname>s
request a connection for each query, then immediately release the
connection back to the pool.
</para>
<para><indexterm><primary>ConnectionRetainMode</primary></indexterm>
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
<link linkend="openjpa.ConnectionRetainMode"><literal>
openjpa.ConnectionRetainMode</literal></link> configuration property.
The property accepts the following values:
</para>
<itemizedlist>
<listitem>
<para><literal>always</literal>: Each <classname>EntityManager
</classname> obtains a single connection and uses it until the
<classname>EntityManager</classname> closes.
</para>
</listitem>
<listitem>
<para><literal>transaction</literal>: 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.
</para>
</listitem>
<listitem>
<para><literal>on-demand</literal>: Connections are obtained
only when needed. This option is equivalent to
the <literal>transaction</literal> 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.
</para>
</listitem>
</itemizedlist>
<para>
You can also specify the connection retain mode of individual
<classname>EntityManager</classname>s when you retrieve them from
the <classname>EntityManagerFactory</classname>. See
<xref linkend="ref_guide_runtime_emfactory"/> for details.
</para>
<para><indexterm><primary>FlushBeforeQueries</primary></indexterm>
The <link linkend="openjpa.FlushBeforeQueries"><literal>
openjpa.FlushBeforeQueries</literal></link> 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
<link linkend="openjpa.IgnoreChanges"><literal>IgnoreChanges</literal></link> property is set to false and the query may involve objects that
have been changed in the current transaction. Legal values are:
</para>
<itemizedlist>
<listitem>
<para><literal>true</literal>: 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.
</para>
</listitem>
<listitem>
<para><literal>false</literal>: Never flush before a query.
</para>
</listitem>
<listitem>
<para><literal>with-connection</literal>: Flush only if the
<classname>EntityManager</classname> has already
established a dedicated connection to the datastore, otherwise
execute the query in-memory.
</para>
<para>
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.
</para>
</listitem>
</itemizedlist>
<para>
The flush mode can also be varied at runtime using the OpenJPA fetch
configuration API, discussed in <xref linkend="ref_guide_runtime"/>.
</para>
<para><indexterm><primary>flush</primary><secondary>automatic</secondary></indexterm>
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.
</para>
<table>
<title>OpenJPA Automatic Flush Behavior</title>
<tgroup rowsep="1" colsep="1" align="left" cols="5">
<colspec colname="col1"/>
<colspec colname="col2"/>
<colspec colname="col3"/>
<colspec colname="col4"/>
<colspec colname="col5"/>
<thead>
<row>
<entry colname="col1"/>
<entry colname="col2">
FlushBeforeQueries = false
</entry>
<entry colname="col3">
FlushBeforeQueries = true
</entry>
<entry colname="col4">
FlushBeforeQueries = with-connection;
ConnectionRetainMode = on-demand
</entry>
<entry colname="col5">
FlushBeforeQueries = with-connection;
ConnectionRetainMode = transaction
or always
</entry>
</row>
</thead>
<tbody>
<row>
<entry colname="col1">
<emphasis role="bold">
IgnoreChanges = true
</emphasis>
</entry>
<entry colname="col2">no flush</entry>
<entry colname="col3">no flush</entry>
<entry colname="col4">no flush</entry>
<entry colname="col5">no flush</entry>
</row>
<row>
<entry colname="col1">
<emphasis role="bold">
IgnoreChanges = false; no tx active
</emphasis>
</entry>
<entry colname="col2">no flush</entry>
<entry colname="col3">no flush</entry>
<entry colname="col4">no flush</entry>
<entry colname="col5">no flush</entry>
</row>
<row>
<entry colname="col1">
<emphasis role="bold">
IgnoreChanges = false; datastore tx active
</emphasis>
</entry>
<entry colname="col2">no flush</entry>
<entry colname="col3">flush</entry>
<entry colname="col4">flush</entry>
<entry colname="col5">flush</entry>
</row>
<row>
<entry colname="col1">
<emphasis role="bold">
IgnoreChanges = false; optimistic tx active
</emphasis>
</entry>
<entry colname="col2">no flush</entry>
<entry colname="col3">flush</entry>
<entry colname="col4">
no flush unless <methodname>flush</methodname> has
already been invoked
</entry>
<entry colname="col5">flush</entry>
</row>
</tbody>
</tgroup>
</table>
<example id="ref_guide_dbsetup_sql92_retain_conf">
<title>Specifying Connection Usage Defaults</title>
<programlisting format="linespecific">
&lt;property name="openjpa.ConnectionRetainMode" value="on-demand"/&gt;
&lt;property name="openjpa.FlushBeforeQueries" value="true"/&gt;
</programlisting>
</example>
<example id="ref_guide_dbsetup_sql92_retain_runtime">
<title>Specifying Connection Usage at Runtime</title>
<programlisting format="linespecific">
import org.apache.openjpa.persistence.*;
...
// obtaining an em with a certain transaction and connection retain mode
OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
EntityManager em = kemf.createEntityManager (PersistenceContextType.EXTENDED,
false, OpenJPAEntityManager.CONN_RETAIN_ALWAYS);
...
// changing the flush mode for an individual EntityManager
OpenJPAEntityManager em = OpenJPAPersistence.cast (em);
FetchPlan fetch = kem.getFetchPlan ();
fetch.setFlushBeforeQueries (FetchPlan.QUERY_FLUSH_TRUE);
</programlisting>
</example>
</section>
<section id="ref_guide_perfpack_batch">
<title>Statement Batching</title>
<indexterm zone="ref_guide_perfpack_batch">
<primary>prepared statement</primary>
<secondary>batching</secondary>
</indexterm>
<para>
In addition to connection pooling and prepared statement caching, OpenJPA
employs statement batching to speed up JDBC updates.
Statement batching is enabled by default for any JDBC driver that
supports it. When batching is on, OpenJPA automatically orders its SQL
statements to maximize the size of each batch. This can result in
large performance gains for transactions that modify a lot of data.
</para>
<para>
You configure statement batching through the system
<ulink url="../apidocs/org/apache/openjpa/jdbc/sql/DBDictionary.html"><classname>DBDictionary</classname></ulink>, which is controlled
by the <link linkend="openjpa.jdbc.DBDictionary"><literal>openjpa.jdbc.DBDictionary</literal></link> configuration
property. The example below shows how to enable and disable statement
batching via your configuration properties.
</para>
<example id="ref_guide_perfpack_batch_ex">
<title>Configuring SQL Batching</title>
<para>
The batch limit is the maximum number of statements OpenJPA will ever
batch together. A value of -1 means "no limit" - this is the
default for most dictionaries. A value of 0 disables batching.
</para>
<programlisting format="linespecific">
&lt;property name="openjpa.jdbc.DBDictionary" value="BatchLimit=25"/&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_dbsetup_lrs">
<title>Large Result Sets</title>
<indexterm zone="ref_guide_dbsetup_lrs">
<primary>large result sets</primary>
</indexterm>
<indexterm>
<primary>JDBC</primary>
<secondary>large result sets</secondary>
<see>large result sets</see>
</indexterm>
<para>
By default, OpenJPA uses standard forward-only JDBC result sets, and
completely instantiates the results of database queries on execution.
When using a JDBC driver that supports version 2.0 or higher
of the JDBC specification, however, you can configure OpenJPA to use
scrolling result sets that may not bring all results into memory
at once. You can also configure the number of result objects OpenJPA
keeps references to, allowing you to traverse potentially enormous
amounts of data without exhausting JVM memory.
</para>
<note>
<para>
You can also configure on-demand loading for individual collection
and map fields via large result set proxies. See
<xref linkend="ref_guide_pc_scos_proxy_lrs"/>.
</para>
</note>
<para>
Use the following properties to configure OpenJPA's handling of result
sets:
</para>
<itemizedlist>
<listitem>
<para><indexterm><primary>FetchBatchSize</primary></indexterm><link linkend="openjpa.FetchBatchSize"><literal>openjpa.FetchBatchSize</literal></link>: The number of
objects to instantiate at once when traversing a result set.
This number will be set as the fetch size on JDBC
<classname>Statement</classname> objects used to obtain
result sets. It also factors in to the number of objects
OpenJPA will maintain a hard reference to when traversing a
query result.
</para>
<para>
The fetch size defaults to -1, meaning all results will be
instantiated immediately on query execution. A value of 0
means to use the JDBC driver's default batch size. Thus to
enable large result set handling, you must set this property
to 0 or to a positive number.
</para>
</listitem>
<listitem>
<para><indexterm><primary>ResultSetType</primary></indexterm><link linkend="openjpa.jdbc.ResultSetType"><literal>
openjpa.jdbc.ResultSetType</literal></link>: The type of result
set to use when executing database queries. This
property accepts the following values, each of which corresponds
exactly to the same-named <classname>java.sql.ResultSet
</classname> constant:
</para>
<itemizedlist>
<listitem>
<para><literal>forward-only</literal>: This is the default.
</para>
</listitem>
<listitem>
<para>
<literal>scroll-sensitive</literal>
</para>
</listitem>
<listitem>
<para>
<literal>scroll-insensitive</literal>
</para>
</listitem>
</itemizedlist>
<para>
Different JDBC drivers treat the different result set types
differently. Not all drivers support all types.
</para>
</listitem>
<listitem>
<para><indexterm><primary>FetchDirection</primary></indexterm><link linkend="openjpa.jdbc.FetchDirection"><literal>
openjpa.jdbc.FetchDirection</literal></link>: The expected order
in which you will access the query results. This property
affects the type of datastructure OpenJPA will use to hold the
results, and is also given to the JDBC driver in case it
can optimize for certain access patterns. This
property accepts the following values, each of which corresponds
exactly to the same-named <classname>java.sql.ResultSet
</classname> FETCH constant:
</para>
<itemizedlist>
<listitem>
<para><literal>forward</literal>: This is the default.
</para>
</listitem>
<listitem>
<para>
<literal>reverse</literal>
</para>
</listitem>
<listitem>
<para>
<literal>unknown</literal>
</para>
</listitem>
</itemizedlist>
<para>
Not all drivers support all fetch directions.
</para>
</listitem>
<listitem>
<para><indexterm><primary>LRSSize</primary></indexterm><link linkend="openjpa.jdbc.LRSSize"><literal>
openjpa.jdbc.LRSSize</literal></link>: The strategy OpenJPA will
use to determine the size of result sets. This property is
<emphasis role="bold">only</emphasis> used if you change the
fetch batch size from its default of -1, so that OpenJPA begins
to use on-demand result loading. Available values are:
</para>
<itemizedlist>
<listitem>
<para><literal>query</literal>: This is the default. The
first time you ask for the size of a query result,
OpenJPA will perform a <literal>SELECT COUNT(*)</literal>
query to determine the number of expected results.
Note that depending on transaction status and settings,
this can mean that the reported size is slightly
different than the actual number of results available.
</para>
</listitem>
<listitem>
<para><literal>last</literal>: If you have chosen a
scrollable result set type, this setting will
use the <methodname>ResultSet.last</methodname>
method to move to the last element in the result
set and get its index. Unfortunately, some JDBC
drivers will bring all results into memory in
order to access the last one. Note that if you
do not choose a scrollable result set type, then
this will behave exactly
like <literal>unknown</literal>. The default
result set type is <literal>forward-only</literal>, so
you must change the result set type in order for this
property to have an effect.
</para>
</listitem>
<listitem>
<para><literal>unknown</literal>: Under this setting OpenJPA
will return <literal>Integer.MAX_VALUE</literal> as
the size for any query result that uses on-demand
loading.
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<example id="ref_guide_dbsetup_lrs_def">
<title>Specifying Result Set Defaults</title>
<programlisting format="linespecific">
&lt;property name="openjpa.FetchBatchSize" value="20"/&gt;
&lt;property name="openjpa.jdbc.ResultSetType" value="scroll-insensitive"/&gt;
&lt;property name="openjpa.jdbc.FetchDirection" value="forward"/&gt;
&lt;property name="openjpa.jdbc.LRSSize" value="last"/&gt;
</programlisting>
</example>
<para>
Many <link linkend="ref_guide_runtime">OpenJPA runtime components
</link> also have methods to configure these properties
on a case-by-case basis through their fetch configuration.
See <xref linkend="ref_guide_runtime"/>.
</para>
<example id="ref_guide_dbsetup_lrs_runtime">
<title>Specifying Result Set Behavior at Runtime</title>
<programlisting format="linespecific">
import java.sql.*;
import org.apache.openjpa.persistence.jdbc.*;
...
Query q = em.createQuery ("select m from Magazine m where m.title = 'JDJ'");
OpenJPAQuery kq = OpenJPAPersistence.cast (q);
JDBCFetchPlan fetch = (JDBCFetchPlan) kq.getFetchPlan ();
fetch.setFetchSize (20);
fetch.setResultSetType (ResultSet.TYPE_SCROLL_INSENSITIVE);
fetch.setFetchDirection (ResultSet.FETCH_FORWARD);
fetch.setLRSSize (JDBCFetchPlan.SIZE_LAST);
List results = (List) q.getResultList ();
</programlisting>
</example>
</section>
<section id="ref_guide_schema_def">
<title>Default Schema</title>
<indexterm zone="ref_guide_schema_def">
<primary>schema</primary>
<secondary>default</secondary>
</indexterm>
<para>
It is common to duplicate a database model in multiple schemas. You
may have one schema for development and another for production, or
different database users may access different schemas. OpenJPA facilitates
these patterns with the <link linkend="openjpa.jdbc.Schema"><literal>
openjpa.jdbc.Schema</literal></link> configuration property. This property
establishes a default schema for any unqualified table names, allowing
you to leave schema names out of your mapping definitions.
</para>
<para>
The <literal>Schema</literal> property also establishes the default
schema for new tables created through OpenJPA tools, such as the mapping
tool covered in <xref linkend="ref_guide_mapping_mappingtool"/>.
</para>
</section>
<section id="ref_guide_schema_info">
<title>Schema Reflection</title>
<indexterm zone="ref_guide_schema_info">
<primary>schema</primary>
<secondary>reflection</secondary>
</indexterm>
<para>
OpenJPA needs information about your database schema for two reasons.
First, it can use schema information at runtime to validate that your
schema is compatible with your persistent class definitions. Second,
OpenJPA requires schema information during development so that it can
manipulate the schema to match your object model. OpenJPA uses the
<literal>SchemaFactory</literal> interface to provide runtime
mapping information, and the <classname>SchemaTool</classname>
for development-time data. Each is presented below.
</para>
<section id="ref_guide_schema_info_list">
<title>Schemas List</title>
<indexterm zone="ref_guide_schema_info_list">
<primary>Schemas</primary>
</indexterm>
<indexterm zone="ref_guide_schema_info_list">
<primary>schema</primary>
<secondary>schemas list</secondary>
</indexterm>
<para>
By default, schema reflection acts on all the schemas your JDBC
driver can "see". You can limit the schemas and tables OpenJPA acts
on with the <literal>openjpa.jdbc.Schemas</literal> configuration
property. This property accepts a comma-separated list of schemas
and tables. To list a schema, list its name. To list a table,
list its full name in the form
<literal>&lt;schema-name&gt;.&lt;table-name&gt;</literal>. If a
table does not have a schema or you do not know its schema, list
its name as <literal>.&lt;table-name&gt;</literal> (notice the
preceding '.'). For example, to list the
<literal>BUSOBJS</literal> schema, the <literal>ADDRESS</literal>
table in the <literal>GENERAL</literal> schema, and the
<literal>SYSTEM_INFO</literal> table, regardless of what schema it
is in, use the string:
</para>
<programlisting format="linespecific">
BUSOBJS,GENERAL.ADDRESS,.SYSTEM_INFO
</programlisting>
<note>
<para>
Some databases are case-sensitive with respect to schema
and table names. Oracle, for example, requires names
in all upper case.
</para>
</note>
</section>
<section id="ref_guide_schema_info_factory">
<title>Schema Factory</title>
<indexterm zone="ref_guide_schema_info_factory">
<primary>schema</primary>
<secondary>SchemaFactory</secondary>
</indexterm>
<para>
OpenJPA relies on the
<ulink url="../apidocs/org/apache/openjpa/jdbc/schema/SchemaFactory.html"><classname>openjpa.jdbc.SchemaFactory</classname></ulink> interface
for runtime schema information. You can control the schema factory
OpenJPA uses through the <literal>openjpa.jdbc.SchemaFactory</literal>
property. There are several built-in options to choose from:
</para>
<itemizedlist>
<listitem>
<para><literal>dynamic</literal>: This is the default setting.
It is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/schema/DynamicSchemaFactory.html"><classname>org.apache.openjpa.jdbc.schema.DynamicSchemaFactory</classname></ulink>. The <classname>DynamicSchemaFactory</classname>
is the most performant schema factory, because it does not
validate mapping information against the database.
Instead, it assumes all object-relational mapping
information is correct, and dynamically builds an
in-memory representation of the schema from your mapping
metadata. When using this factory, it is important that
your mapping metadata correctly represent your database's
foreign key constraints so that OpenJPA can order its SQL
statements to meet them.
</para>
</listitem>
<listitem>
<para><literal>native</literal>: This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/schema/LazySchemaFactory.html"><classname>org.apache.openjpa.jdbc.schema.LazySchemaFactory</classname></ulink>. As persistent classes are loaded by the
application, OpenJPA reads their metadata and
object-relational mapping information. This
factory uses the <classname>java.sql.DatabaseMetaData
</classname> interface to reflect on the schema and ensure
that it is consistent with the mapping data being read.
Because the factory doesn't reflect on a table
definition until that table is mentioned by the
mapping information, we call it "lazy". Use this
factory if you want up-front validation that your mapping
metadata is consistent with the database during development.
This factory accepts the following important properties:
</para>
<itemizedlist>
<listitem>
<para><literal>ForeignKeys</literal>: Set to <literal>
true</literal> to automatically read foreign key
information during schema validation.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><literal>table</literal>: This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/schema/TableSchemaFactory.html"><classname>org.apache.openjpa.jdbc.schema.TableSchemaFactory</classname></ulink>. This schema factory stores
schema information as an XML document in a database
table it creates for this purpose. If your
JDBC driver doesn't support the
<classname>java.sql.DatabaseMetaData</classname>
standard interface, but you still want some schema
validation to occur at runtime, you might use this
factory. It is not recommended for most users, though,
because it is easy for the stored XML schema definition
to get out-of-synch with the actual database. This factory
accepts the following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>Table</literal>: The name of the table
to create to store schema information. Defaults
to <literal>OPENJPA_SCHEMA</literal>.
</para>
</listitem>
<listitem>
<para><literal>PrimaryKeyColumn</literal>: The name of
the table's numeric primary key column. Defaults
to <literal>ID</literal>.
</para>
</listitem>
<listitem>
<para><literal>SchemaColumn</literal>: The name of
the table's string column for holding the schema
definition as an XML string. Defaults to
<literal>SCHEMA_DEF</literal>.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para><literal>file</literal>: This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/jdbc/schema/FileSchemaFactory.html"><classname>org.apache.openjpa.jdbc.schema.FileSchemaFactory</classname></ulink>. This factory is a lot like the
<classname>TableSchemaFactory</classname>, and has the
same advantages and disadvantages. Instead
of storing its XML schema definition in a database
table, though, it stores it in a file. This factory
accepts the following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>File</literal>: The resource name
of the XML schema file. By default, the factory
looks for a resource called <filename>
package.schema</filename>, located in any top-level
directory of the <literal>CLASSPATH</literal> or
in the top level of any jar in your
<literal>CLASSPATH</literal>.
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<para>
You can switch freely between schema factories at any time.
The XML file format used by some factories is detailed
in <xref linkend="ref_guide_schema_xml"/>. As with any OpenJPA
plugin, you can can also implement your own schema factory if you
have needs not met by the existing options.
</para>
</section>
</section>
<section id="ref_guide_schema_schematool">
<title>Schema Tool</title>
<indexterm zone="ref_guide_schema_schematool">
<primary>schema</primary>
<secondary>schema tool</secondary>
</indexterm>
<indexterm>
<primary>schema</primary>
<secondary>DDL</secondary>
<see>DDL</see>
</indexterm>
<indexterm>
<primary>SQL</primary>
<secondary>DDL</secondary>
<see>DDL</see>
</indexterm>
<indexterm zone="ref_guide_schema_schematool">
<primary>DDL</primary>
<secondary>with schema tool</secondary>
</indexterm>
<para>
Most users will only access the schema tool indirectly, through the
interfaces provided by other tools. You may find, however, that the
schema tool is a powerful utility in its own right.
The schema tool has two functions:
</para>
<orderedlist>
<listitem>
<para>
To reflect on the current database schema, optionally
translating it to an XML representation for further
manipulation.
</para>
</listitem>
<listitem>
<para>
To take in an XML schema definition, calculate the differences
between the XML and the existing database schema, and apply the
necessary changes to make the database match the XML.
</para>
</listitem>
</orderedlist>
<para>
The <link linkend="ref_guide_schema_xml">XML format</link>
used by the schema tool abstracts away the differences between
SQL dialects used by different database vendors. The tool also
automatically adapts its SQL to meet foreign key dependencies.
Thus the schema tool is useful as a general way to manipulate schemas.
</para>
<para>
You can invoke the schema tool through the
<literal>schematool</literal> shell/bat script included in the
OpenJPA distribution, or through its Java class,
<ulink url="../apidocs/org/apache/openjpa/jdbc/schema/SchemaTool.html"><classname>org.apache.openjpa.jdbc.schema.SchemaTool</classname></ulink>. In
addition to the universal flags of the <link linkend="ref_guide_conf">
configuration framework</link>, the schema tool accepts the following
command line arguments:
</para>
<itemizedlist>
<listitem>
<para><literal>-ignoreErrors/-i &lt;true/t | false/f&gt;</literal>:
If <literal>false</literal>, an exception will
be thrown if the tool encounters any database errors.
Defaults to <literal>false</literal>.
</para>
</listitem>
<listitem>
<para><literal>-file/-f &lt;stdout | output file&gt;</literal>:
Use this option to write a SQL script for the planned
schema modifications, rather them committing them to the
database. When used in conjunction with the
<literal>export</literal> or <literal>reflect</literal> actions, the named file will be used to write the exported schema XML.
If the file names a resource in the
<literal>CLASSPATH</literal>, data will be written
to that resource. Use <literal>stdout</literal> to
write to standard output. Defaults to
<literal>stdout</literal>.
</para>
</listitem>
<listitem>
<para><literal>-openjpaTables/-kt &lt;true/t | false/f&gt;</literal>:
When reflecting on the schema, whether to reflect on tables
and sequences whose names start with <literal>OPENJPA_</literal>.
Certain OpenJPA components may use such tables - for example,
the <literal>table</literal> schema factory option covered
in <xref linkend="ref_guide_schema_info_factory"/>.
When using other actions, <literal>openjpaTables</literal>
controls whether these tables can be dropped. Defaults to
<literal>false</literal>.
</para>
</listitem>
<listitem>
<para><literal>-dropTables/-dt &lt;true/t | false/f&gt;</literal>:
Set this option to <literal>true</literal> to drop tables
that appear to be unused during <literal>retain</literal>
and <literal>refresh</literal> actions. Defaults to
<literal>true</literal>.
</para>
</listitem>
<listitem>
<para><literal>-dropSequences/-dsq &lt;true/t | false/f&gt;</literal>:
Set this option to <literal>true</literal> to drop sequences
that appear to be unused during <literal>retain</literal>
and <literal>refresh</literal> actions. Defaults to
<literal>true</literal>.
</para>
</listitem>
<listitem>
<para><literal>-sequences/-sq &lt;true/t | false/f&gt;</literal>:
Whether to manipulate sequences.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para><literal>-indexes/-ix &lt;true/t | false/f&gt;</literal>:
Whether to manipulate indexes on existing tables.
Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para><literal>-primaryKeys/-pk &lt;true/t | false/f&gt;</literal>:
Whether to manipulate primary keys on existing
tables. Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para><literal>-foreignKeys/-fk &lt;true/t | false/f&gt;</literal>:
Whether to manipulate foreign keys on
existing tables. Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para><literal>-record/-r &lt;true/t | false/f&gt;</literal>: Use
<literal>false</literal> to prevent writing the schema
changes made by the tool to the current
<link linkend="ref_guide_schema_info_factory"><literal>schema factory</literal></link>. Defaults to
<literal>true</literal>.
</para>
</listitem>
<listitem>
<para><literal>-schemas/-s &lt;schema list&gt;</literal>: A list
of schema and table names that OpenJPA should access during
this run of the schema tool. This is equivalent to setting
the <link linkend="openjpa.jdbc.Schemas">openjpa.jdbc.Schemas</link>
property for a single run.
</para>
</listitem>
</itemizedlist>
<para>
The schema tool also accepts an <literal>-action</literal> or
<literal>-a</literal> flag. The available actions are:
</para>
<itemizedlist>
<listitem>
<para><literal>add</literal>: This is the default action if you do
not specify one. It brings the schema up-to-date with
the given XML document by adding tables, columns, indexes,
etc. This action never drops any schema components.
</para>
</listitem>
<listitem>
<para><literal>retain</literal>: Keep all schema components in
the given XML definition, but drop the rest from the
database. This action never adds any schema components.
</para>
</listitem>
<listitem>
<para><literal>drop</literal>: Drop all schema components in the
schema XML. Tables will only be dropped if they would have
0 columns after dropping all columns listed in the XML.
</para>
</listitem>
<listitem>
<para><literal>refresh</literal>: Equivalent to
<literal>retain</literal>, then <literal>add</literal>.
</para>
</listitem>
<listitem>
<para><literal>build</literal>: Generate SQL to build a schema
matching the one in the given XML file. Unlike
<literal>add</literal>, this option does not take into account
the fact that part of the schema defined in the XML file might
already exist in the database. Therefore, this action is
typically used in conjunction with the <literal>-file</literal>
flag to write a SQL script. This script can later be used to
recreate the schema in the XML.
</para>
</listitem>
<listitem>
<para><literal>reflect</literal>: Generate an XML representation
of the current database schema.
</para>
</listitem>
<listitem>
<para><literal>createDB</literal>: Generate SQL to re-create the
current database. This action is typically used in
conjunction with the <literal>-file</literal> flag to
write a SQL script that can be used to recreate the current
schema on a fresh database.
</para>
</listitem>
<listitem>
<para><literal>dropDB</literal>: Generate SQL to drop the
current database. Like <literal>createDB</literal>, this
action can be used with the <literal>-file</literal>
flag to script a database drop rather than perform it.
</para>
</listitem>
<listitem>
<para><literal>import</literal>: Import the given XML schema
definition into the current schema factory. Does nothing
if the factory does not store a record of the schema.
</para>
</listitem>
<listitem>
<para><literal>export</literal>: Export the current schema
factory's stored schema definition to XML. May produce
an empty file if the factory does not store a record of
the schema.
</para>
</listitem>
</itemizedlist>
<note>
<para>
The schema tool manipulates tables, columns, indexes, constraints,
and sequences. It cannot create or drop
the database schema objects in which the tables reside,
however. If your XML documents refer to named database
schemas, those schemas must exist.
</para>
</note>
<para>
We present some examples of schema tool usage below.
</para>
<example id="ref_guide_schema_schematool_create">
<title>Schema Creation</title>
<indexterm zone="ref_guide_schema_schematool_create">
<primary>schema</primary>
<secondary>create with schema tool</secondary>
</indexterm>
<para>
Add the necessary schema components to the database to match
the given XML document, but don't drop any data:
</para>
<programlisting format="linespecific">
schematool targetSchema.xml
</programlisting>
</example>
<example id="ref_guide_schema_schematool_script">
<title>SQL Scripting</title>
<para>
Repeat the same action as the first example, but this time
don't change the database. Instead, write any planned changes
to a SQL script:
</para>
<programlisting format="linespecific">
schematool -f script.sql targetSchema.xml
</programlisting>
<para>
Write a SQL script that will re-create the current database:
</para>
<programlisting format="linespecific">
schematool -a createDB -f script.sql
</programlisting>
</example>
<example id="ref_guide_schema_schematool_drop">
<title>Schema Drop</title>
<para>
Drop the current database:
</para>
<programlisting format="linespecific">
schematool -a dropDB
</programlisting>
</example>
<example id="ref_guide_schema_schematool_reflect">
<title>Schema Reflection</title>
<indexterm zone="ref_guide_schema_schematool_reflect">
<primary>schema</primary>
<secondary>reflection</secondary>
<tertiary>with schema tool</tertiary>
</indexterm>
<para>
Write an XML representation of the current schema to file
<filename>schema.xml</filename>.
</para>
<programlisting format="linespecific">
schematool -a reflect -f schema.xml
</programlisting>
</example>
</section>
<section id="ref_guide_schema_xml">
<title>XML Schema Format</title>
<indexterm zone="ref_guide_schema_xml">
<primary>schema</primary>
<secondary>XML representation</secondary>
</indexterm>
<para>
The <link linkend="ref_guide_schema_schematool">schema tool</link> and
<link linkend="ref_guide_schema_info_factory">
schema factories</link> all use the same XML format to represent
database schema. The Document Type Definition (DTD) for
schema information is presented below, followed by examples
of schema definitions in XML.
</para>
<programlisting format="linespecific">
&lt;!ELEMENT schemas (schema)+&gt;
&lt;!ELEMENT schema (table|sequence)+&gt;
&lt;!ATTLIST schema name CDATA #IMPLIED&gt;
&lt;!ELEMENT sequence EMPTY&gt;
&lt;!ATTLIST sequence name CDATA #REQUIRED&gt;
&lt;!ATTLIST sequence initial-value CDATA #IMPLIED&gt;
&lt;!ATTLIST sequence increment CDATA #IMPLIED&gt;
&lt;!ATTLIST sequence allocate CDATA #IMPLIED&gt;
&lt;!ELEMENT table (column|index|pk|fk)+&gt;
&lt;!ATTLIST table name CDATA #REQUIRED&gt;
&lt;!ELEMENT column EMPTY&gt;
&lt;!ATTLIST column name CDATA #REQUIRED&gt;
&lt;!ATTLIST column type (array | bigint | binary | bit | blob | char | clob
| date | decimal | distinct | double | float | integer | java_object
| longvarbinary | longvarchar | null | numeric | other | real | ref
| smallint | struct | time | timestamp | tinyint | varbinary | varchar)
#REQUIRED&gt;
&lt;!ATTLIST column not-null (true|false) "false"&gt;
&lt;!ATTLIST column auto-assign (true|false) "false"&gt;
&lt;!ATTLIST column default CDATA #IMPLIED&gt;
&lt;!ATTLIST column size CDATA #IMPLIED&gt;
&lt;!ATTLIST column decimal-digits CDATA #IMPLIED&gt;
&lt;!-- the type-name attribute can be used when you want OpenJPA to --&gt;
&lt;!-- use a particular SQL type declaration when creating the --&gt;
&lt;!-- column. It is up to you to ensure that this type is --&gt;
&lt;!-- compatible with the JDBC type used in the type attribute. --&gt;
&lt;!ATTLIST column type-name CDATA #IMPLIED&gt;
&lt;!-- the 'column' attribute of indexes, pks, and fks can be used --&gt;
&lt;!-- when the element has only one column (or for foreign keys, --&gt;
&lt;!-- only one local column); in these cases the on/join child --&gt;
&lt;!-- elements can be omitted --&gt;
&lt;!ELEMENT index (on)*&gt;
&lt;!ATTLIST index name CDATA #REQUIRED&gt;
&lt;!ATTLIST index column CDATA #IMPLIED&gt;
&lt;!ATTLIST index unique (true|false) "false"&gt;
&lt;!-- the 'logical' attribute of pks should be set to 'true' if --&gt;
&lt;!-- the primary key does not actually exist in the database, --&gt;
&lt;!-- but the given column should be used as a primary key for --&gt;
&lt;!-- O-R purposes --&gt;
&lt;!ELEMENT pk (on)*&gt;
&lt;!ATTLIST pk name CDATA #IMPLIED&gt;
&lt;!ATTLIST pk column CDATA #IMPLIED&gt;
&lt;!ATTLIST pk logical (true|false) "false"&gt;
&lt;!ELEMENT on EMPTY&gt;
&lt;!ATTLIST on column CDATA #REQUIRED&gt;
&lt;!-- fks with a delete-action of 'none' are similar to logical --&gt;
&lt;!-- pks; they do not actually exist in the database, but --&gt;
&lt;!-- represent a logical relation between tables (or their --&gt;
&lt;!-- corresponding Java classes) --&gt;
&lt;!ELEMENT fk (join)*&gt;
&lt;!ATTLIST fk name CDATA #IMPLIED&gt;
&lt;!ATTLIST fk deferred (true|false) "false"&gt;
&lt;!ATTLIST fk to-table CDATA #REQUIRED&gt;
&lt;!ATTLIST fk column CDATA #IMPLIED&gt;
&lt;!ATTLIST fk delete-action (cascade|default|exception|none|null) "none"&gt;
&lt;!ELEMENT join EMPTY&gt;
&lt;!ATTLIST join column CDATA #REQUIRED&gt;
&lt;!ATTLIST join to-column CDATA #REQUIRED&gt;
&lt;!ATTLIST join value CDATA #IMPLIED&gt;
&lt;!-- unique constraint --&gt;
&lt;!ELEMENT unique (on)*&gt;
&lt;!ATTLIST unique name CDATA #IMPLIED&gt;
&lt;!ATTLIST unique column CDATA #IMPLIED&gt;
&lt;!ATTLIST unique deferred (true|false) "false"&gt;
</programlisting>
<example id="ref_guide_schema_xml_basic">
<title>Basic Schema</title>
<para>
A very basic schema definition.
</para>
<programlisting format="linespecific">
&lt;schemas&gt;
&lt;schema&gt;
&lt;sequence name="S_ARTS"/&gt;
&lt;table name="ARTICLE"&gt;
&lt;column name="TITLE" type="varchar" size="255" not-null="true"/&gt;
&lt;column name="AUTHOR_FNAME" type="varchar" size="28"&gt;
&lt;column name="AUTHOR_LNAME" type="varchar" size="28"&gt;
&lt;column name="CONTENT" type="clob"&gt;
&lt;/table&gt;
&lt;table name="AUTHOR"&gt;
&lt;column name="FIRST_NAME" type="varchar" size="28" not-null="true"&gt;
&lt;column name="LAST_NAME" type="varchar" size="28" not-null="true"&gt;
&lt;/table&gt;
&lt;/schema&gt;
&lt;/schemas&gt;
</programlisting>
</example>
<example id="ref_guide_schema_xml_full">
<title>Full Schema</title>
<para>
Expansion of the above schema with primary keys, constraints,
and indexes, some of which span multiple columns.
</para>
<programlisting format="linespecific">
&lt;schemas&gt;
&lt;schema&gt;
&lt;sequence name="S_ARTS"/&gt;
&lt;table name="ARTICLE"&gt;
&lt;column name="TITLE" type="varchar" size="255" not-null="true"/&gt;
&lt;column name="AUTHOR_FNAME" type="varchar" size="28"&gt;
&lt;column name="AUTHOR_LNAME" type="varchar" size="28"&gt;
&lt;column name="CONTENT" type="clob"&gt;
&lt;pk column="TITLE"/&gt;
&lt;fk to-table="AUTHOR" delete-action="exception"&gt;
&lt;join column="AUTHOR_FNAME" to-column="FIRST_NAME"/&gt;
&lt;join column="AUTHOR_LNAME" to-column="LAST_NAME"/&gt;
&lt;/fk&gt;
&lt;index name="ARTICLE_AUTHOR"&gt;
&lt;on column="AUTHOR_FNAME"/&gt;
&lt;on column="AUTHOR_LNAME"/&gt;
&lt;/index&gt;
&lt;/table&gt;
&lt;table name="AUTHOR"&gt;
&lt;column name="FIRST_NAME" type="varchar" size="28" not-null="true"&gt;
&lt;column name="LAST_NAME" type="varchar" size="28" not-null="true"&gt;
&lt;pk&gt;
&lt;on column="FIRST_NAME"/&gt;
&lt;on column="LAST_NAME"/&gt;
&lt;/pk&gt;
&lt;/table&gt;
&lt;/schema&gt;
&lt;/schemas&gt;
</programlisting>
</example>
</section>
</chapter>