blob: b3bed5d447fc3e0c1778a459ffeedd700e5040ac [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<chapter id="ref_guide_dbsetup">
<title>
JDBC
</title>
<indexterm zone="ref_guide_dbsetup">
<primary>
JDBC
</primary>
</indexterm>
<para>
OpenJPA 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 simple <classname>javax.sql.DataSource</classname>
implementation. 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, 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>
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>
<listitem>
<para>
<indexterm>
<primary>
SQL
</primary>
<secondary>
PrettyPrint
</secondary>
</indexterm>
<literal>PrettyPrint</literal>: Boolean indicating whether to pretty-print
logged SQL statements.
</para>
</listitem>
<listitem>
<para>
<indexterm>
<primary>
SQL
</primary>
<secondary>
PrettyPrintLineLength
</secondary>
</indexterm>
<literal>PrettyPrintLineLength</literal>: The maximum number of characters in
each pretty-printed SQL line.
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
<example id="ref_guide_dbsetup_builtin_ex">
<title>
Properties for the OpenJPA DataSource
</title>
<programlisting>
&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="PrettyPrint=true, PrettyPrintLineLength=80"/&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 <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
<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>
The 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 features 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>
&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, use the
<literal>jta-data-source</literal> element of your <filename>
persistence.xml</filename> file or 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> using the <literal>non-jta-data-source
</literal> <filename>persistence.xml</filename> element, or OpenJPA's 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"/>.
</para>
<example id="ref_guide_enterprise_xa_conf_ex">
<title>
Managed DataSource Configuration
</title>
<programlisting>
&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;/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="../javadoc/org/apache/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_jpa">
<title>
Using the EntityManager's Connection
</title>
<programlisting>
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_jpa">
<title>
Using the EntityManagerFactory's DataSource
</title>
<programlisting>
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 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="../javadoc/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="../javadoc/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="../javadoc/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/org/apache/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="../javadoc/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="../javadoc/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="../javadoc/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="../javadoc/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="../javadoc/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="../javadoc/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="../javadoc/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="../javadoc/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="../javadoc/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="../javadoc/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="../javadoc/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>
&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.SupportsTimestampNanos">
<para>
<indexterm>
<primary>
SupportsTimestampNanos
</primary>
</indexterm>
<literal>SupportsTimestampNanos</literal>: Whether the database supports nanoseconds with TIMESTAMP columns. 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.SelectWords">
<para>
<indexterm>
<primary>
SQL
</primary>
<secondary>
SelectWords
</secondary>
</indexterm>
<literal>SelectWords</literal>: A comma-separated list of keywords which may be
used to start a SELECT statement for this database. If an application executes
a native SQL statement which begins with SelectWords OpenJPA will treat the
statement as a SELECT statement rather than an UPDATE statement.
</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>
<listitem id="DBDictionary.BlobBufferSize">
<para>
<indexterm>
<primary>
BLOB
</primary>
<secondary>
BlobBufferSize
</secondary>
</indexterm>
<literal>BlobBufferSize</literal>: This property establishes the buffer size in
the <literal>INSERT/UPDATE</literal> operations with an
<literal>java.io.InputStream</literal>This is only used with OpenJPA's
<xref linkend="ref_guide_streamsupport"/>. Defaults to 50000.
</para>
</listitem>
<listitem id="DBDictionary.ClobBufferSize">
<para>
<indexterm>
<primary>
CLOB
</primary>
<secondary>
ClobBufferSize
</secondary>
</indexterm>
<literal>ClobBufferSize</literal>: This property establish the buffer size in
the <literal>INSERT/UPDATE</literal> operations with a
<literal>java.io.Reader</literal>This is only used with OpenJPA's
<xref linkend="ref_guide_streamsupport"/>. Defaults to 50000.
</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>
<listitem id="MySQLDictionary.OptimizeMultiTableDeletes">
<para>
<indexterm>
<primary>
MySQL
</primary>
<secondary>
OptimizeMultiTableDeletes
</secondary>
</indexterm>
<literal>OptimizeMultiTableDeletes</literal>: MySQL as of version 4.0.0
supports multiple tables in <literal>DELETE</literal> statements. When
this option is set, OpenJPA will use that syntax when doing bulk deletes
from multiple tables. This can happen when the
<literal>deleteTableContents</literal> <literal>SchemaTool</literal>
action is used. (See <xref linkend="ref_guide_schema_schematool"/> for
more info about <literal>deleteTableContents</literal>.) Defaults to
<literal>false</literal>, since the statement may fail if using InnoDB
tables and delete constraints.
</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_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>openjpa-project/src/doc/manual/ref_guide_dbsetup.xml
</itemizedlist>
<example id="ref_guide_dbsetup_isoex">
<title>
Specifying a Transaction Isolation
</title>
<programlisting>
&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>
&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>
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(JoinSyntax.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
<classname>EntityManagerFactory</classname> to access a different
database. If your application accesses multiple databases, we recommend that you
maintain a separate persistence unit 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.
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>
<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>
&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>
import org.apache.openjpa.persistence.*;
// obtaining an em with a certain connection retain mode
Map props = new HashMap();
props.put("openjpa.ConnectionRetainMode", "always");
EntityManager em = emf.createEntityManager(props);
</programlisting>
</example>
</section>
<section id="ref_guide_dbsetup_stmtbatch">
<title>
Statement Batching
</title>
<indexterm zone="ref_guide_dbsetup_stmtbatch">
<primary>
Statement Batching
</primary>
</indexterm>
<indexterm>
<primary>
JDBC
</primary>
<secondary>
statement batching
</secondary>
<see>
statement batching
</see>
</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 DBDictionary, which is
controlled by the openjpa.jdbc.DBDictionary configuration property. You can
enable the statement batching by setting the batchLimit in the value. The batch
limit is the maximum number of statements OpenJPA will ever batch
together. A value has the following meaning:
<itemizedlist>
<listitem>
<para>
<literal>-1</literal>: Unlimited number of statements for a batch.
</para>
</listitem>
<listitem>
<para>
<literal>0</literal>: Disable batch support. This is the default for most
dictionaries.
</para>
</listitem>
<listitem>
<para>
<literal>any positive number</literal>: Maximum number of statements for a batch.
</para>
</listitem>
</itemizedlist>
<note>
<para>
By default, the batch support is based on each Dictionary to define the default
batch limit. Currently only DB2 and Oracle dictionaries are set the default
batch limit to 100. The default batch limit for the rest of the dictionaries is set
to zero (disabled).
</para>
</note>
</para>
<para>
The example below shows how to enable and disable statement batching via
your configuration properties.
</para>
<example id="ref_guide_dbsetup_stmtbatch_exmple1">
<title>
Enable SQL statement batching
</title>
<programlisting>
&lt;property name="openjpa.jdbc.DBDictionary" value="db2(batchLimit=25)"/&gt;
&lt;property name="openjpa.jdbc.DBDictionary" value="oracle(batchLimit=-1)"/&gt;
Or
&lt;property name="openjpa.jdbc.DBDictionary" value="batchLimit=25"/&gt;
&lt;property name="openjpa.jdbc.DBDictionary" value="batchLimit=-1"/&gt;
</programlisting>
</example>
<example id="ref_guide_dbsetup_stmtbatch_exmple2">
<title>
Disable SQL statement batching
</title>
<programlisting>
&lt;property name="openjpa.jdbc.DBDictionary" value="db2(batchLimit=0)"/&gt;
Or
&lt;property name="openjpa.jdbc.DBDictionary" value="batchLimit=0"/&gt;
</programlisting>
</example>
<par>
By default, org.apache.openjpa.jdbc.kernel.BatchingConstraintUpdateManager
is the default statement batching implementation. OPENJPA also
provides another update manager
org.apache.openjpa.jdbc.kernel.BatchingOperationOrderUpdateManager for the
statements that required ordering. You can plug-in this update manager through
the "openjpa.jdbc.UpdateManager" property. Or you can plug-in your own
statement batching implementation by providing the implementation that extends
from AbstractUpdateManager, ConstraitUpdateManager or OperationOrderUpdateManager.
Add this implementation
class as a property in the persistence.xml file. For example, a custom
statement batching implementation mycomp.MyUpdateManager extends
ConstraitUpdateManager. You specify this implementation in the persistence.xml
file as the following example:
</par>
<example id="ref_guide_dbsetup_stmtbatch_exmple3">
<title>
Plug-in custom statement batching implementation
</title>
<programlisting>
&lt;property name="openjpa.jdbc.UpdateManager" value="mycomp.MyUpdateManager"/&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>
&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>
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.setFetchBatchSize(20);
fetch.setResultSetType(ResultSetType.SCROLL_INSENSITIVE);
fetch.setFetchDirection(FetchDirection.FORWARD);
fetch.setLRSSizeAlgorithm(LRSSizeAlgorithm.LAST);
List results = 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>
<para>
If the entities are mapped to the same table name but with different schema
name within one <literal>PersistenceUnit</literal> intentionally, and the
strategy of <literal>GeneratedType.AUTO</literal> is used to generate the ID
for each entity, a schema name for each entity must be explicitly declared
either through the annotation or the mapping.xml file. Otherwise, the mapping
tool only creates the tables for those entities with the schema names under
each schema. In addition, there will be only one
<literal>OPENJPA_SEQUENCE_TABLE</literal> created for all the entities within
the <literal>PersistenceUnit</literal> if the entities are not identified
with the schema name.
Read <xref linkend="ref_guide_sequence"/> in the Reference Guide.
</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>
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="../javadoc/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="../javadoc/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="../javadoc/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.
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="../javadoc/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="../javadoc/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 its Java class,
<ulink url="../javadoc/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/-ot &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. Multiple actions can be composed in a comma-separated list.
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>
<listitem>
<para>
<literal>deleteTableContents</literal>: Execute SQL to delete all rows from
all tables that OpenJPA knows about.
</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>
java org.apache.openjpa.jdbc.schema.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>
java org.apache.openjpa.jdbc.schema.SchemaTool -f script.sql targetSchema.xml
</programlisting>
<para>
Write a SQL script that will re-create the current database:
</para>
<programlisting>
java org.apache.openjpa.jdbc.schema.SchemaTool -a createDB -f script.sql
</programlisting>
</example>
<example id="ref_guide_schema_schematool_table_cleanup">
<title>
Table Cleanup
</title>
<indexterm zone="ref_guide_schema_schematool_table_cleanup">
<primary>
schema
</primary>
<secondary>
refresh schema and delete all contents of all tables
</secondary>
</indexterm>
<indexterm zone="ref_guide_schema_schematool_table_cleanup">
<primary>
testing
</primary>
<secondary>
refresh schema and delete all contents of all tables
</secondary>
</indexterm>
<para>
Refresh the schema and delete all contents of all tables that OpenJPA
knows about:
</para>
<programlisting>
java org.apache.openjpa.jdbc.schema.SchemaTool -a refresh,deleteTableContents
</programlisting>
</example>
<example id="ref_guide_schema_schematool_drop">
<title>
Schema Drop
</title>
<para>
Drop the current database:
</para>
<programlisting>
java org.apache.openjpa.jdbc.schema.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>
java org.apache.openjpa.jdbc.schema.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>
&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|unique)+&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>
&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>
&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>