JDBCJDBC
OpenJPA JPA 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.
Using the OpenJPA DataSourceDataSourceOpenJPAconnectionsDataSource
OpenJPA includes its own javax.sql.DataSource
implementation, complete with configurable connection pooling
and prepared statement caching. If you choose to use
OpenJPA's DataSource, then you must specify
the following properties:
ConnectionUserNameopenjpa.ConnectionUserName:
The JDBC user name for connecting to the database.
ConnectionPasswordopenjpa.ConnectionPassword:
The JDBC password for the above user.
ConnectionURLopenjpa.ConnectionURL:
The JDBC URL for the database.
ConnectionDriverNameopenjpa.ConnectionDriverName:
The JDBC driver class.
To configure advanced features such as connection pooling and prepared
statement caching, or to configure the underlying JDBC driver, use the
following optional properties. The syntax of these property strings
follows the syntax of OpenJPA plugin parameters described in
.
ConnectionPropertiesopenjpa.ConnectionProperties:
If the listed driver is an instance of
java.sql.Driver, this string will
be parsed into a Properties instance,
which will then be used to obtain database connections through
the Driver.connect(String url,
Properties props) method. If, on the other hand,
the listed driver is a
javax.sql.DataSource,
the string will be treated as a plugin properties string, and
matched to the bean setter methods of the
DataSource instance.
ConnectionFactoryPropertiesopenjpa.ConnectionFactoryProperties:
OpenJPA's built-in DataSource
allows you to set the following options via
this plugin string:
connectionspoolingExceptionActionExceptionAction: The action to
take when when a connection that has thrown an exception
is returned to the pool. Set to destroy
to destroy the connection. Set to
validate to validate the connection (subject
to the TestOnReturn,
TestOnBorrow, and other test settings).
Set to none to ignore the fact that
the connection has thrown an exception, and assume it
is still usable. Defaults to
destroy.
connectionspoolingMaxActiveMaxActive: The maximum number of
database connections in use at one time. A value of 0
disables connection pooling. Defaults to 8.
This is the maximum number of connections that OpenJPA will
give out to your application. If a connection is
requested while MaxActive other
connections are in use, OpenJPA will wait for
MaxWait milliseconds for a connection
to be returned, and will then throw an exception if no
connection was made available.
connectionspoolingMaxIdleMaxIdle: The maximum number of
idle database connections to keep in the pool. Defaults
to 8. If this number is less than
MaxActive, then OpenJPA will close
extra connections that are returned to the pool if
there are already MaxIdle available
connections. This allows for
unexpected or atypical load while still maintaining
a relatively small pool when there is less load on the
system.
connectionspoolingMaxTotalMaxTotal: The maximum number of
database connections in the pool, whether active or
idle. Defaults to -1, meaning no limit (the limit will
be dictated by MaxActive and
MaxIdle for each unique user name).
connectionspoolingMaxWaitMaxWait: The maximum number of
milliseconds to wait for a free database connection to
become available before giving up. Defaults to 3000.
connectionspoolingMinEvictableIdleTimeMillisMinEvictableIdleTimeMillis: The
minimum number of milliseconds that a database
connection can sit idle before it becomes a candidate
for eviction from the pool. Defaults to 30 minutes.
Set to 0 to never evict a connection based on idle
time alone.
connectionspoolingRollbackOnReturnRollbackOnReturn:
Force all connections to be rolled back when they
are retuned to the pool. If false, the
DataSource will
only roll back connections when it detects that there
have been any transactional updates on the connection.
connectionspoolingTestOnBorrowTestOnBorrow: Whether to to validate
database connections before obtaining them from the
pool. Note that validation
only consists of a call to the connection's
isClosed method unless you
specify a ValidationSQL string.
Defaults to true.
connectionspoolingTestOnReturnTestOnReturn: Set to true
to validate database connections when they
are returned to the pool. Note that validation
only consists of a call to the connection's
isClosed method unless you
specify a ValidationSQL string.
connectionspoolingTestWhileIdleTestWhileIdle: Set to
true to periodically validate idle
database connections.
connectionspoolingTimeBetweenEvictionRunsMillisTimeBetweenEvictionRunsMillis: The
number of milliseconds between runs of the eviction
thread. Defaults to -1, meaning
the eviction thread will never run.
connectionspoolingTrackParametersTrackParameters: When
true, OpenJPA will track the
parameters that were set for all
PreparedStatements that
are executed or batched so that they can be
included in error messages.
Defaults to true.
connectionspoolingValidationSQLValidationSQL: A simple SQL query to
issue to validate a database connection. If this
property is not set, then the only validation performed
is to use the Connection.isClosed
method. The following table shows the
default settings for different databases. If a database
is not shown, this property defaults to null.
Validation SQL DefaultsDatabaseSQLDB2
SELECT DISTINCT(CURRENT TIMESTAMP)
FROM SYSIBM.SYSTABLES
Empress
SELECT DISTINCT(TODAY)
FROM SYS_TABLES
Informix
SELECT DISTINCT CURRENT TIMESTAMP
FROM INFORMIX.SYSTABLES
MySQL
SELECT NOW()
Oracle
SELECT SYSDATE FROM DUAL
Postgres
SELECT NOW()
SQLServer
SELECT GETDATE()
Sybase
SELECT GETDATE()
To disable validation SQL, set this property to
an empty string, as in
connectionspoolingClosePoolSQLClosePoolSQL: A simple SQL statement
to execute when the connection pool is completely
closed. This can be used, for example, to cleanly
issue a shutdown statement to a file-based
database.
connectionspoolingValidationTimeoutValidationTimeout:
The minimum number of milliseconds that must elapse
before a connection will ever be re-validated. This
property is typically used with TestOnBorrow
or TestOnReturn to
reduce the number of validations performed, because
the same connection is often borrowed and returned many
times in a short span. Defaults to
300000 (5 minutes).
connectionspoolingWarningActionWarningAction:
The action to take when a
SQLWarning is detected on a
connection. Possible values are:
ignore: Warnings will
not be checked for, and will be ignored.
This is the default.
trace:
The warning will be logged on the
TRACE
channel of the JDBC log.
info:
The warning will be logged on the
INFO
channel of the JDBC log.
warn:
The warning will be logged on the
WARN
channel of the JDBC log.
error:
The warning will be logged on the
ERROR
channel of the JDBC log.
throw:
All SQLWarning
instances will be thrown as if they were
errors.
handle:
The SQLWarning
instance will be passed through the
handleWarning
method of
org.apache.openjpa.jdbc.sql.DBDictionary,
which allows a custom extension
of the dictionary to use heuristic-based
warning handling.
connectionspoolingWhenExhaustedActionWhenExhaustedAction: The action to
take when there are no available database connections
in the pool. Set to exception to
immediately throw an exception. Set to
block to block until a connection is
available or the maximum wait time is exceeded. Set to
grow to automatically grow the pool.
Defaults to block.
Additionally, the following properties are available whether
you use OpenJPA's built-in DataSource
or a third-party's:
prepared statementpoolingMaxCachedStatementsMaxCachedStatements: The maximum
number of
java.sql.PreparedStatements
to cache. Statement caching can dramatically speed up
some databases. Defaults to 50 for OpenJPA's
DataSource, and 0 for
third-party DataSources. Most
third-party DataSources do not
benefit from OpenJPA's prepared statement cache, because
each returned connection has a unique hash code,
making it impossible for OpenJPA to match connections to
their cached statements.
JDBCQueryTimeoutQueryTimeout: The maximum number of
seconds the JDBC driver will wait for a statement to
execute.
Properties for the OpenJPA DataSource
<property name="openjpa.ConnectionUserName" value="user"/>
<property name="openjpa.ConnectionPassword" value="pass"/>
<property name="openjpa.ConnectionURL" value="jdbc:hsqldb:db-hypersonic"/>
<property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/>
<property name="openjpa.ConnectionFactoryProperties"
value="MaxActive=50, MaxIdle=10, ValidationTimeout=50000, MaxCachedStatements=100, ValidationSQL=''"/>
Using a Third-Party DataSourceDataSourcethird party
You can use OpenJPA with any third-party
javax.sql.DataSource. There are multiple ways
of telling OpenJPA about a DataSource:
ConnectionFactory
Set the DataSource into the map passed
to Persistence.createEntityManagerFactory
under the openjpa.ConnectionFactory key.
ConnectionFactoryName
Bind the DataSource into JNDI, and then
specify its location in the
jta-data-source or
non-jta-data-source element of the
JPA XML
format (depending on whether the DataSource
is managed by JTA), or in the
openjpa.ConnectionFactoryName property.
ConnectionDriverName
Specify the full class name of the
DataSource implementation in the
openjpa.ConnectionDriverName 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 DataSource with
the properties in the openjpa.ConnectionProperties setting.
Some advanced features of OpenJPA's own DataSource
can also be used with third-party implementations. OpenJPA layers on top
of the third-party DataSource to provide the
extra functionality. To configure these advanced features, including
prepared statement caching, use the
openjpa.ConnectionFactoryProperties property
described in the previous section.
Properties File for a Third-Party DataSource
<property name="openjpa.ConnectionDriverName" value="oracle.jdbc.pool.OracleDataSource"/>
<property name="openjpa.ConnectionProperties"
value="PortNumber=1521, ServerName=saturn, DatabaseName=solarsid, DriverType=thin"/>
<property name="openjpa.ConnectionFactoryProperties" value="QueryTimeout=5000"/>
Managed and XA DataSourcesDataSourcemanagedDataSourceXAConnectionFactoryMode
Certain application servers automatically enlist their
DataSources 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 DataSource
is managed by the application server, set the
openjpa.ConnectionFactoryMode property to
managed.
Note that OpenJPA can only use managed
DataSources when it is also
integrating with the application server's managed transactions.
Also
note that all XA DataSources are enlisted,
and you must set this property when using any XA
DataSource.
When using a managed DataSource, you
should also configure a second unmanaged
DataSource 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
DataSource just as the first, but use the various "2"
connection properties, such as
openjpa.ConnectionFactory2Name
or openjpa.Connection2DriverName.
These properties are outlined in .
If your second DataSource is also bound to
JNDI, you can use JPA XML's non-jta-data-source
to specify its location.
Typically, though, you will use
OpenJPA's built-in implementation
for the second DataSource
(see ).
Managed DataSource Configuration
<!-- managed DataSource -->
<jta-data-source>java:/OracleXASource</jta-data-source>
<properties>
<!-- use OpenJPA's built-in DataSource for unmanaged connections -->
<property name="openjpa.Connection2UserName" value="scott"/>
<property name="openjpa.Connection2Password" value="tiger"/>
<property name="openjpa.Connection2URL" value="jdbc:oracle:thin:@CROM:1521:OpenJPADB"/>
<property name="openjpa.Connection2DriverName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="openjpa.ConnectionFactory2Properties" value="MaxActive=20, MaxIdle=10"/>
<!-- managed transaction and enlisted configuration -->
<property name="openjpa.TransactionMode" value="managed"/>
<property name="openjpa.ConnectionFactoryMode" value="managed"/>
</properties>
Runtime Access to DataSourceconnectionsaccessing DataSourceJDBCaccessing DataSource
The JPA standard defines how to access JDBC connections from enterprise
beans. OpenJPA also provides APIs to access an
EntityManager's connection, or to retrieve a connection
directly from the EntityManagerFactory's
DataSource.
The OpenJPAEntityManager.getConnection method
returns an EntityManager's connection. If the
EntityManager does not already have a connection,
it will obtain one. The returned connection is only guaranteed to be
transactionally consistent with other EntityManager
operations if the EntityManager is
in a managed or non-optimistic transaction, if the
EntityManager has flushed in the current transaction, or if
you have used the OpenJPAEntityManager.beginStore
method to ensure that a datastore transaction is in progress. Always
close the returned connection before attempting any other
EntityManager operations. OpenJPA will ensure that
the underlying native connection is not released if a datastore
transaction is in progress.
Using the EntityManager's Connection
import java.sql.*;
import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
Connection conn = (Connection) kem.getConnection ();
// do JDBC stuff
conn.close ();
The example below shows how to use a connection directly from the
DataSource, rather than using an
EntityManager's connection.
Using the EntityManagerFactory's DataSource
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 ();
Database SupportDBDictionaryrelational databaseOpenJPA supportDBDictionary
OpenJPA JPA 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
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.
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 org.apache.openjpa.jdbc.sql.DBDictionary to use.
The DBDictionary abstracts away the differences
between databases. You can plug a dictionary into OpenJPA using the
openjpa.jdbc.DBDictionary
configuration property. The built-in dictionaries
are listed below. If you are using an unsupported database, you may
have to write your own DBDictionary subclass,
a simple process.
Microsoft Accessaccess: Dictionary for Microsoft
Access. This is an alias for the
org.apache.openjpa.jdbc.sql.AccessDictionary class.
DB2db2: Dictionary for IBM's DB2 database.
This is an alias for the
org.apache.openjpa.jdbc.sql.DB2Dictionary class.
Derbyderby: Dictionary for the Apache Derby
database. This is an alias for the
org.apache.openjpa.jdbc.sql.DerbyDictionary class.
Empressempress: Dictionary for Empress database
This is an alias for the
org.apache.openjpa.jdbc.sql.EmpressDictionary class.
FoxProfoxpro: Dictionary for Microsoft
Visual FoxPro. This is an alias for the
org.apache.openjpa.jdbc.sql.FoxProDictionary class.
Hypersonic SQLhsql: Dictionary for the Hypersonic SQL
database. This is an alias for the
org.apache.openjpa.jdbc.sql.HSQLDictionary class.
Informixinformix: Dictionary for the Informix
database. This is an alias for the
org.apache.openjpa.jdbc.sql.InformixDictionary class.
JDataStorejdatastore: Dictionary for Borland
JDataStore. This is an alias for the
org.apache.openjpa.jdbc.sql.JDataStoreDictionary class.
MySQLmysql: Dictionary for the MySQL
database. This is an alias for the
org.apache.openjpa.jdbc.sql.MySQLDictionary class.
Oracleoracle: Dictionary for Oracle.
This is an alias for the
org.apache.openjpa.jdbc.sql.OracleDictionary class.
Pointbasepointbase: Dictionary for Pointbase Embedded
database. This is an alias for the
org.apache.openjpa.jdbc.sql.PointbaseDictionary class.
PostgreSQLpostgres: Dictionary for PostgreSQL.
This is an alias for the
org.apache.openjpa.jdbc.sql.PostgresDictionary class.
SQLServersqlserver: Dictionary for Microsoft's
SQLServer database. This is an alias for the
org.apache.openjpa.jdbc.sql.SQLServerDictionary class.
Sybasesybase: Dictionary for Sybase.
This is an alias for the
org.apache.openjpa.jdbc.sql.SybaseDictionary class.
The example below demonstrates how to set a dictionary and configure
its properties in your configuration file. The DBDictionary
property uses OpenJPA's
plugin syntax.
Specifying a DBDictionary
<property name="openjpa.jdbc.DBDictionary" value="hsql(SimulateLocking=true)"/>
DBDictionary Properties
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 DBDictionary
for an unsupported database.
JDBCDriverVendorDriverVendor: The vendor of the particular
JDBC driver you are using. Some dictionaries must alter their
behavior depending on the driver vendor. See the
VENDOR_XXX constants defined in your
dictionary's Javadoc for available options.
SQLCatalogSeparatorCatalogSeparator:
The string the database uses to delimit between
the schema name and the table name. This is typically
".", which is the default.
DDLCreatePrimaryKeysCreatePrimaryKeys: If
false, then do not create database
primary keys for identifiers. Defaults to
true.
DDLConstraintNameModeConstraintNameMode: When
creating constraints, whether to put the constraint name
before the definition (before), just after
the constraint type name (mid), or after the
constraint definition (after).
Defaults to before.
DDLMaxTableNameLengthMaxTableNameLength: The maximum number
of characters in a table name. Defaults to 128.
DDLMaxColumnNameLengthMaxColumnNameLength: The maximum number
of characters in a column name. Defaults to 128.
DDLMaxConstraintNameLengthMaxConstraintNameLength: The maximum number
of characters in a constraint name. Defaults to 128.
DDLMaxIndexNameLengthindexesMaxIndexNameLengthMaxIndexNameLength: The maximum number
of characters in an index name. Defaults to 128.
DDLMaxAutoAssignNameLengthMaxAutoAssignNameLength: 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 31.
indexesMaxIndexesPerTableMaxIndexesPerTable: The maximum number
of indexes that can be placed on a single table. Defaults to
no limit.
foreign keysSupportsForeignKeysSupportsForeignKeys: Whether the database
supports foreign keys. Defaults to true.
unique constraintsSupportsUniqueConstraintsSupportsUniqueConstraints: Whether the
database supports unique constraints. Defaults to true.
foreign keysSupportsDeferredConstraintsSupportsDeferredConstraints: Whether the
database supports deferred constraints. Defaults to true.
foreign keysSupportsRestrictDeleteActionSupportsRestrictDeleteAction: Whether the
database supports the RESTRICT foreign key delete action.
Defaults to true.
foreign keysSupportsCascadeDeleteActionSupportsCascadeDeleteAction: Whether the
database supports the CASCADE foreign key delete action.
Defaults to true.
foreign keysSupportsNullDeleteActionSupportsNullDeleteAction: Whether the
database supports the SET NULL foreign key delete action.
Defaults to true.
foreign keysSupportsDefaultDeleteActionSupportsDefaultDeleteAction: Whether the
database supports the SET DEFAULT foreign key delete action.
Defaults to true.
DDLSupportsAlterTableWithAddColumnSupportsAlterTableWithAddColumn: Whether the
database supports adding a new column in an ALTER TABLE
statement. Defaults to true.
DDLSupportsAlterTableWithDropColumnSupportsAlterTableWithDropColumn: Whether
the database supports dropping a column in an ALTER TABLE
statement. Defaults to true.
SQLReservedWordsReservedWords: A comma-separated list of
reserved words for this database, beyond the standard SQL92
keywords.
schemareflectionSystemTablesSystemTables: A comma-separated list of
table names that should be ignored.
schemareflectionSystemSchemasSystemSchemas: A comma-separated list of
schema names that should be ignored.
schemareflectionSchemaCaseSchemaCase: The case to use when querying
the database metadata about schema components. Defaults to
making all names upper case. Available values are:
upper, lower, preserve.
connectionsValidationSQLSQLValidationSQLValidationSQL: The SQL used to
validate that a connection is still in a valid state. For
example, "SELECT SYSDATE FROM DUAL" for
Oracle.
connectionsInitializationSQLSQLInitializationSQLInitializationSQL: A piece of SQL to issue
against the database whenever a connection is retrieved from
the DataSource.
joinsJoinSyntaxJoinSyntax: The SQL join syntax
to use in select statements. See
.
joinsCrossJoinClauseCrossJoinClause: The clause to use for
a cross join (cartesian product).
Defaults to CROSS JOIN.
joinsInnerJoinClauseInnerJoinClause: The clause to use for
an inner join. Defaults to INNER JOIN.
joinsOuterJoinClauseOuterJoinClause: The clause to use for
an left outer join.
Defaults to LEFT OUTER JOIN.
joinsRequiresConditionForCrossJoinRequiresConditionForCrossJoin: 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.
SQLToUpperCaseFunctionToUpperCaseFunction: SQL function call for
for converting a string to upper case. Use the token
{0} to represent the argument.
SQLToLowerCaseFunctionToLowerCaseFunction: Name of the SQL function
for converting a string to lower case. Use the token
{0} to represent the argument.
SQLStringLengthFunctionStringLengthFunction: Name of the SQL
function for getting the length of a string. Use the token
{0} to represent the argument.
SQLSubstringFunctionNameSubstringFunctionName: Name of the SQL
function for getting the substring of a string.
SQLDistinctCountColumnSeparatorDistinctCountColumnSeparator:
The string the database uses to delimit between column
expressions in a SELECT COUNT(DISTINCT column-list)
clause. Defaults to null for most databases,
meaning that multiple columns in a distinct COUNT clause are
not supported.
SQLForUpdateClauselockingForUpdateClauseForUpdateClause: The clause to append to
SELECT statements to issue queries that
obtain pessimistic locks. Defaults to
FOR UPDATE.
SQLTableForUpdateClauselockingTableForUpdateClauseTableForUpdateClause: The clause to append
to the end of each table alias in queries that obtain
pessimistic locks. Defaults to null.
lockingSupportsSelectForUpdateSupportsSelectForUpdate: If true, then the
database supports SELECT statements with a
pessimistic locking clause. Defaults to true.
lockingSupportsLockingWithDistinctClauseSupportsLockingWithDistinctClause: If true,
then the database supports FOR UPDATE
select clauses with DISTINCT clauses.
lockingSupportsLockingWithOuterJoinSupportsLockingWithOuterJoin: If true, then
the database supports FOR UPDATE select
clauses with outer join queries.
lockingSupportsLockingWithInnerJoinSupportsLockingWithInnerJoin: If true, then
the database supports FOR UPDATE select
clauses with inner join queries.
lockingSupportsLockingWithMultipleTablesSupportsLockingWithMultipleTables: If true,
then the database supports FOR UPDATE select
clauses that select from multiple tables.
lockingSupportsLockingWithOrderClauseSupportsLockingWithOrderClause: If true,
then the database supports FOR UPDATE
select clauses with ORDER BY clauses.
lockingSupportsLockingWithSelectRangeSupportsLockingWithSelectRange: If true,
then the database supports FOR UPDATE
select clauses with queries that select a range of data using
LIMIT, TOP or the
database equivalent. Defaults to true.
lockingSimulateLockingSimulateLocking: Some databases
do not support pessimistic locking, which will result in
an exception when you attempt a pessimistic
transaction. Setting this property to
true bypasses the locking check to
allow pessimistic transactions even on databases that
do not support locking. Defaults to false.
JDBCQueryTimeoutSupportsQueryTimeoutSupportsQueryTimeout: If true, then the
JDBC driver supports calls to
java.sql.Statement.setQueryTimeout.
aggregateshavingSupportsHavingSupportsHaving: Whether this database
supports HAVING clauses in selects.
Queryresult rangeSupportsSelectStartIndexSupportsSelectStartIndex: Whether this
database can create a select that skips the first N results.
Queryresult rangeSupportsSelectEndIndexSupportsSelectEndIndex: Whether this
database can create a select that is limited to the first N
results.
SQLSupportsSubselectJPQLsubselectsSupportsSubselectSupportsSubselect: Whether this database
supports subselects in queries.
SQLRequiresAliasForSubselectJPQLsubselectsRequiresAliasForSubselectRequiresAliasForSubselect: If true, then
the database requires that subselects in a FROM clause be
assigned an alias.
SupportsMultipleNontransactionalResultSets:
If true, then a nontransactional connection is capable
of having multiple open ResultSet
instances.
persistent fieldsStorageLimitationsFatalStorageLimitationsFatal: 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.
persistent fieldsStoreLargeNumbersAsStringsStoreLargeNumbersAsStrings: 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 BigInteger and
BigDecimal 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
false.
persistent fieldsStoreCharsAsNumbersStoreCharsAsNumbers: Set this property
to false to store Java
char fields as CHAR
values rather than numbers. Defaults to true.
BLOBUseGetBytesForBlobsUseGetBytesForBlobs: If true, then
ResultSet.getBytes will be used to
obtain blob data rather than
ResultSet.getBinaryStream.
BLOBUseGetObjectForBlobsUseGetObjectForBlobs: If true, then
ResultSet.getObject will be used to
obtain blob data rather than
ResultSet.getBinaryStream.
BLOBUseSetBytesForBlobsUseSetBytesForBlobs: If true, then
PreparedStatement.setBytes
will be used to set blob data, rather than
PreparedStatement.setBinaryStream.
CLOBUseGetStringForClobsUseGetStringForClobs: If true, then
ResultSet.getString will be used to
obtain clob data rather than
ResultSet.getCharacterStream.
CLOBUseSetStringForClobsUseSetStringForClobs: If true, then
PreparedStatement.setString
will be used to set clob data, rather than
PreparedStatement.setCharacterStream.
DDLCharacterColumnSizeCharacterColumnSize: The default size of
varchar and char columns.
Typically 255.
DDLArrayTypeNameArrayTypeName: The overridden default
column type for java.sql.Types.ARRAY.
This is only used when the schema is generated by
the mappingtool.
DDLBigintTypeNameBigintTypeName: The overridden default
column type for java.sql.Types.BIGINT.
This is only used when the schema is generated by
the mappingtool.
DDLBinaryTypeNameBinaryTypeName: The overridden default
column type for java.sql.Types.BINARY.
This is only used when the schema is generated by
the mappingtool.
DDLBitTypeNameBitTypeName: The overridden default
column type for java.sql.Types.BIT.
This is only used when the schema is generated by
the mappingtool.
DDLBlobTypeNameBLOBBlobTypeNameBlobTypeName: The overridden default
column type for java.sql.Types.BLOB.
This is only used when the schema is generated by
the mappingtool.
DDLCharTypeNameCharTypeName: The overridden default
column type for java.sql.Types.CHAR.
This is only used when the schema is generated by
the mappingtool.
DDLClobTypeNameCLOBClobTypeNameClobTypeName: The overridden default
column type for java.sql.Types.CLOB.
This is only used when the schema is generated by
the mappingtool.
DDLDateTypeNameDateTypeName: The overridden default
column type for java.sql.Types.DATE.
This is only used when the schema is generated by
the mappingtool.
DDLDecimalTypeNameDecimalTypeName: The overridden default
column type for java.sql.Types.DECIMAL.
This is only used when the schema is generated by
the mappingtool.
DDLDistinctTypeNameDistinctTypeName: The overridden default
column type for java.sql.Types.DISTINCT.
This is only used when the schema is generated by
the mappingtool.
DDLDoubleTypeNameDoubleTypeName: The overridden default
column type for java.sql.Types.DOUBLE.
This is only used when the schema is generated by
the mappingtool.
DDLFloatTypeNameFloatTypeName: The overridden default
column type for java.sql.Types.FLOAT.
This is only used when the schema is generated by
the mappingtool.
DDLIntegerTypeNameIntegerTypeName: The overridden default
column type for java.sql.Types.INTEGER.
This is only used when the schema is generated by
the mappingtool.
DDLJavaObjectTypeNameJavaObjectTypeName: The overridden default
column type for java.sql.Types.JAVAOBJECT.
This is only used when the schema is generated by
the mappingtool.
DDLLongVarbinaryTypeNameLongVarbinaryTypeName: The overridden default
column type for java.sql.Types.LONGVARBINARY.
This is only used when the schema is generated by
the mappingtool.
DDLLongVarcharTypeNameLongVarcharTypeName: The overridden default
column type for java.sql.Types.LONGVARCHAR.
This is only used when the schema is generated by
the mappingtool.
DDLNullTypeNameNullTypeName: The overridden default
column type for java.sql.Types.NULL.
This is only used when the schema is generated by
the mappingtool.
DDLNumericTypeNameNumericTypeName: The overridden default
column type for java.sql.Types.NUMERIC.
This is only used when the schema is generated by
the mappingtool.
DDLOtherTypeNameOtherTypeName: The overridden default
column type for java.sql.Types.OTHER.
This is only used when the schema is generated by
the mappingtool.
DDLRealTypeNameRealTypeName: The overridden default
column type for java.sql.Types.REAL.
This is only used when the schema is generated by
the mappingtool.
DDLRefTypeNameRefTypeName: The overridden default
column type for java.sql.Types.REF.
This is only used when the schema is generated by
the mappingtool.
DDLSmallintTypeNameSmallintTypeName: The overridden default
column type for java.sql.Types.SMALLINT.
This is only used when the schema is generated by
the mappingtool.
DDLStructTypeNameStructTypeName: The overridden default
column type for java.sql.Types.STRUCT.
This is only used when the schema is generated by
the mappingtool.
DDLTimeTypeNameTimeTypeName: The overridden default
column type for java.sql.Types.TIME.
This is only used when the schema is generated by
the mappingtool.
DDLTimestampTypeNameTimestampTypeName: The overridden default
column type for java.sql.Types.TIMESTAMP.
This is only used when the schema is generated by
the mappingtool.
DDLTinyintTypeNameTinyintTypeName: The overridden default
column type for java.sql.Types.TINYINT.
This is only used when the schema is generated by
the mappingtool.
DDLVarbinaryTypeNameVarbinaryTypeName: The overridden default
column type for java.sql.Types.VARBINARY.
This is only used when the schema is generated by
the mappingtool.
DDLVarcharTypeNameVarcharTypeName: The overridden default
column type for java.sql.Types.VARCHAR.
This is only used when the schema is generated by
the mappingtool.
schemaUseSchemaNameUseSchemaName: If false,
then avoid including the schema name in table name references.
Defaults to true.
schemareflectionTableTypesTableTypes: Comma-separated list of table
types to use when looking for tables during schema reflection,
as defined in the
java.sql.DatabaseMetaData.getTableInfo
JDBC method. An example is:
"TABLE,VIEW,ALIAS". Defaults to
"TABLE".
schemareflectionSupportsSchemaForGetTablesSupportsSchemaForGetTables: If false, then
the database driver does not support using
the schema name for schema reflection on table names.
schemareflectionSupportsSchemaForGetColumnsSupportsSchemaForGetColumns: If false, then
the database driver does not support using
the schema name for schema reflection on column names.
schemareflectionSupportsNullTableForGetColumnsSupportsNullTableForGetColumns:
If true, then the database supports passing a
null parameter to
DatabaseMetaData.getColumns
as an optimization to get information about all the tables.
Defaults to true.
schemareflectionSupportsNullTableForGetPrimaryKeysSupportsNullTableForGetPrimaryKeys:
If true, then the database supports passing a
null parameter to
DatabaseMetaData.getPrimaryKeys
as an optimization to get information about all the tables.
Defaults to false.
schemareflectionSupportsNullTableForGetIndexInfoSupportsNullTableForGetIndexInfo:
If true, then the database supports passing a
null parameter to
DatabaseMetaData.getIndexInfo
as an optimization to get information about all the tables.
Defaults to false.
schemareflectionSupportsNullTableForGetImportedKeysSupportsNullTableForGetImportedKeys:
If true, then the database supports passing a
null parameter to
DatabaseMetaData.getImportedKeys
as an optimization to get information about all the tables.
Defaults to false.
schemareflectionUseGetBestRowIdentifierForPrimaryKeysUseGetBestRowIdentifierForPrimaryKeys:
If true, then metadata queries will use
DatabaseMetaData.getBestRowIdentifier
to obtain information about primary keys, rather than
DatabaseMetaData.getPrimaryKeys.
schemareflectionRequiresAutoCommitForMetaDataRequiresAutoCommitForMetadata:
If true, then the JDBC driver requires that autocommit
be enabled before any schema interrogation operations can
take place.
persistent fieldsautomatic field valuesAutoAssignClauseAutoAssignClause: The column definition
clause to append to a creation statement. For example,
"AUTO_INCREMENT" 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 mappingtool.
DDLAutoAssignTypeNamepersistent fieldsautomatic field valuesAutoAssignTypeNameAutoAssignTypeName: The column type name
for auto-increment columns. For example,
"SERIAL" 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 mappingtool.
persistent fieldsautomatic field valuesLastGeneratedKeyQueryLastGeneratedKeyQuery: The query to issue
to obtain the last automatically generated key for an
auto-increment column. For example,
"select @@identity" for Sybase.
This property is set automatically in the
dictionary, and should not need to be overridden.
SequenceNextSequenceQueryNextSequenceQuery: A SQL string for
obtaining a native sequence value. May use a placeholder of
{0} for the variable sequence name. Defaults
to a database-appropriate value.
MySQLDictionary PropertiesMySQLDBDictionary
The mysql dictionary also understands the
following properties:
MySQLDriverDeserializesBlobsDriverDeserializesBlobs: Many MySQL
drivers automatically deserialize BLOBs on calls to
ResultSet.getObject.
The MySQLDictionary overrides the
standard DBDictionary.getBlobObject
method to take this into account. If your driver does not
deserialize automatically, set this property to
false.
MySQLTableTypeTableType: The MySQL table type to
use when creating tables. Defaults to
innodb.
MySQLUseClobsUseClobs: Some older versions of
MySQL do not handle clobs correctly. To enable clob
functionality, set this to true. Defaults to
false.
OracleDictionary PropertiesOracleDBDictionary
The oracle dictionary understands the
following additional properties:
OracleUseTriggersForAutoAssignpersistent fieldsautomatic field valuesUseTriggersForAutoAssignUseTriggersForAutoAssign:
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
AutoAssignSequenceName parameter
will hold the value of the new primary key for rows that
have been inserted.
For more details on auto-increment support, see
.
OracleAutoAssignSequenceNamepersistent fieldsautomatic field valuesAutoAssignSequenceNameAutoAssignSequenceName:
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
"SEQ_<table name>".
OracleMaxEmbeddedBlobSizeBLOBMaxEmbeddedBlobSizeMaxEmbeddedBlobSize:
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.
OracleMaxEmbeddedClobSizeCLOBMaxEmbeddedClobSizeMaxEmbeddedClobSize:
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.
UseSetFormOfUseForUnicode:
Prior to Oracle 10i, statements executed against
unicode capable columns (the NCHAR,
NVARCHAR, NCLOB
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
OraclePreparedStatement.setFormOfUse.
For more details, see the Oracle
Readme For NChar.
Note that this can only work if OpenJPA is able to
access the underlying
OraclePreparedStatement 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.
SQLFactory PropertiesSQLSQLFactory
Some aspects of advanced SQL aren't configured through the
DBDictionary, but through the
SQLFactory. The
openjpa.jdbc.SQLFactory configuration property is
a plugin string
you can use to configure the following parameters:
prepared statementbatchingBatchLimitBatchLimit: The maximum number of SQL
update statements to batch together. Set to 0 to disable
statement batching, or -1 for no limit. See
.
prepared statementbatchingBatchParameterLimitBatchParameterLimit: The maximum number of
parameters that can be batched together for a single
batch update. Some databases can only handle a certain
total number of prepared statement parameters in a single
batch. This value will cause OpenJPA to flush a SQL batch
once the number of batched statements times the number of
bound parameters per statement exceeds this value.
Set to 0 to disable SQL batching, or -1 for no limit.
prepared statementbatchingSupportsUpdateCountsForBatchSupportsUpdateCountsForBatch: Whether the
JDBC driver correctly returns the set of update counts when
a batch statement is executed.
prepared statementbatchingSupportsTotalCountsForBatchSupportsTotalCountsForBatch: If a JDBC
driver doesn't support batch update counts, whether it
at least returns the total number of updates made when a batch
statement is executed.
SQLunionSupportsUnionSupportsUnion: Whether the database supports
SQL UNIONs.
SQLunionSupportsUnionWithUnalignedOrderingSupportsUnionWithUnalignedOrdering: Whether
the database supports SQL UNIONs that order on columns that are
not in the same position in all the SELECTs that make up the
UNION.
The defaults for these properties depend on the database in use.
Configuring SQLFactory Properties
<property name="openjpa.jdbc.SQLFactory" value="BatchLimit=100, SupportsUnion=true"/>
Setting the Transaction IsolationtransactionsisolationJDBCtransaction isolationTransactionIsolation
OpenJPA typically retains the default transaction isolation level
of the JDBC driver. However, you can specify a transaction isolation
level to use through the openjpa.jdbc.TransactionIsolation configuration
property. The following is a list of standard isolation levels.
Note that not all databases support all isolation levels.
default: Use the JDBC driver's default
isolation level. OpenJPA uses this option if you do not
explicitly specify any other.
none: No transaction isolation.
read-committed: Dirty reads are
prevented; non-repeatable reads and phantom reads can
occur.
read-uncommitted: Dirty reads,
non-repeatable reads and phantom reads can occur.
repeatable-read: Dirty reads and
non-repeatable reads are prevented; phantom reads can occur.
serializable: Dirty reads,
non-repeatable reads, and phantom reads are prevented.
Specifying a Transaction Isolation
<property name="openjpa.jdbc.TransactionIsolation" value="repeatable-read"/>
Setting the SQL Join Syntaxjoinssyntax optionsSQLjoin syntax
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 DBDictionary. OpenJPA only supports outer
joins when using SQL 92 syntax or a database-specific syntax with outer
join support.
The
openjpa.jdbc.DBDictionary plugin accepts the
the JoinSyntax property to set
the system's default syntax. The available values are:
traditional: Traditional SQL
join syntax; outer joins are not supported.
database: The database's native
join syntax. Databases that do not have a native
syntax will default to one of the other options.
sql92: ANSI SQL92 join syntax.
Outer joins are supported. Not all databases
support this syntax.
You can change the join syntax at runtime through the OpenJPA
fetch configuration API, which is described in
.
Specifying the Join Syntax Default
<property name="openjpa.jdbc.DBDictionary" value="JoinSyntax=sql92"/>
Specifying the Join Syntax at Runtime
import org.apache.openjpa.persistence.jdbc.*;
...
Query q = em.createQuery ("select m from Magazine m where m.title = 'JDJ'");
OpenJPAQuery kq = OpenJPAPersistence.cast (q);
JDBCFetchPlan fetch = (JDBCFetchPlan) kq.getFetchPlan ();
fetch.setJoinSyntax (JDBCFetchPlan.JOIN_SYNTAX_SQL92);
List results = q.getResultList ();
Accessing Multiple Databasesrelational databaseaccessing multiple databases
Through the properties we've covered thus far, you can configure each
EntityManagerFactory
to access a different database. If your application accesses multiple
databases, we recommend that you maintain a separate properties file
for each one. This will allow you to easily load the appropriate
resource for each database at runtime, and to give the correct
configuration file to OpenJPA's command-line tools during development.
Configuring the Use of JDBC Connectionsconnectionsusage
In its default configuration, OpenJPA obtains JDBC connections on
an as-needed basis. OpenJPA EntityManagers do
not retain a connection to the database unless they are in a datastore
transaction or there are open Query results that
are using a live JDBC result set. At all other times, including
during optimistic transactions, EntityManagers
request a connection for each query, then immediately release the
connection back to the pool.
ConnectionRetainMode
In some cases, it may be more efficient to retain connections for
longer periods of time. You can configure OpenJPA's use of JDBC
connections through the
openjpa.ConnectionRetainMode configuration property.
The property accepts the following values:
always: Each EntityManager
obtains a single connection and uses it until the
EntityManager closes.
transaction: A connection is obtained
when each transaction begins (optimistic or datastore),
and is released when the transaction completes.
Non-transactional connections are obtained on-demand.
on-demand: Connections are obtained
only when needed. This option is equivalent to
the transaction option when datastore
transactions are used. For optimistic transactions,
though, it means that a connection will be retained only
for the duration of the datastore flush and commit process.
You can also specify the connection retain mode of individual
EntityManagers when you retrieve them from
the EntityManagerFactory. See
for details.
FlushBeforeQueries
The
openjpa.FlushBeforeQueries configuration property controls
another aspect of connection usage: whether to flush transactional
changes before executing object queries. This setting only applies to
queries that would otherwise have to be executed in-memory because the
IgnoreChanges property is set to false and the query may involve objects that
have been changed in the current transaction. Legal values are:
true: Always flush rather than executing
the query in-memory. If the current transaction is
optimistic, OpenJPA will begin a non-locking datastore
transaction. This is the default.
false: Never flush before a query.
with-connection: Flush only if the
EntityManager has already
established a dedicated connection to the datastore, otherwise
execute the query in-memory.
This option is useful if
you use long-running optimistic transactions and want to
ensure that these transactions do not consume database
resources until commit. OpenJPA's behavior with this option
is dependent on the transaction status and mode, as well as
the configured connection retain mode described earlier in
this section.
The flush mode can also be varied at runtime using the OpenJPA fetch
configuration API, discussed in .
flushautomatic
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.
OpenJPA Automatic Flush Behavior
FlushBeforeQueries = false
FlushBeforeQueries = true
FlushBeforeQueries = with-connection;
ConnectionRetainMode = on-demand
FlushBeforeQueries = with-connection;
ConnectionRetainMode = transaction
or always
IgnoreChanges = true
no flushno flushno flushno flush
IgnoreChanges = false; no tx active
no flushno flushno flushno flush
IgnoreChanges = false; datastore tx active
no flushflushflushflush
IgnoreChanges = false; optimistic tx active
no flushflush
no flush unless flush has
already been invoked
flush
Specifying Connection Usage Defaults
<property name="openjpa.ConnectionRetainMode" value="on-demand"/>
<property name="openjpa.FlushBeforeQueries" value="true"/>
Specifying Connection Usage at Runtime
import org.apache.openjpa.persistence.*;
...
// obtaining an em with a certain transaction and connection retain mode
OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
EntityManager em = kemf.createEntityManager (PersistenceContextType.EXTENDED,
false, OpenJPAEntityManager.CONN_RETAIN_ALWAYS);
...
// changing the flush mode for an individual EntityManager
OpenJPAEntityManager em = OpenJPAPersistence.cast (em);
FetchPlan fetch = kem.getFetchPlan ();
fetch.setFlushBeforeQueries (FetchPlan.QUERY_FLUSH_TRUE);
Statement Batchingprepared statementbatching
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.
You configure statement batching through the system
DBDictionary, which is controlled
by the openjpa.jdbc.DBDictionary configuration
property. The example below shows how to enable and disable statement
batching via your configuration properties.
Configuring SQL Batching
The batch limit is the maximum number of statements OpenJPA will ever
batch together. A value of -1 means "no limit" - this is the
default for most dictionaries. A value of 0 disables batching.
<property name="openjpa.jdbc.DBDictionary" value="BatchLimit=25"/>
Large Result Setslarge result setsJDBClarge result setslarge result sets
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.
You can also configure on-demand loading for individual collection
and map fields via large result set proxies. See
.
Use the following properties to configure OpenJPA's handling of result
sets:
FetchBatchSizeopenjpa.FetchBatchSize: The number of
objects to instantiate at once when traversing a result set.
This number will be set as the fetch size on JDBC
Statement 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.
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.
ResultSetType
openjpa.jdbc.ResultSetType: 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 java.sql.ResultSet
constant:
forward-only: This is the default.
scroll-sensitivescroll-insensitive
Different JDBC drivers treat the different result set types
differently. Not all drivers support all types.
FetchDirection
openjpa.jdbc.FetchDirection: 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 java.sql.ResultSet
FETCH constant:
forward: This is the default.
reverseunknown
Not all drivers support all fetch directions.
LRSSize
openjpa.jdbc.LRSSize: The strategy OpenJPA will
use to determine the size of result sets. This property is
only 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:
query: This is the default. The
first time you ask for the size of a query result,
OpenJPA will perform a SELECT COUNT(*)
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.
last: If you have chosen a
scrollable result set type, this setting will
use the ResultSet.last
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 unknown. The default
result set type is forward-only, so
you must change the result set type in order for this
property to have an effect.
unknown: Under this setting OpenJPA
will return Integer.MAX_VALUE as
the size for any query result that uses on-demand
loading.
Specifying Result Set Defaults
<property name="openjpa.FetchBatchSize" value="20"/>
<property name="openjpa.jdbc.ResultSetType" value="scroll-insensitive"/>
<property name="openjpa.jdbc.FetchDirection" value="forward"/>
<property name="openjpa.jdbc.LRSSize" value="last"/>
Many OpenJPA runtime components
also have methods to configure these properties
on a case-by-case basis through their fetch configuration.
See .
Specifying Result Set Behavior at Runtime
import java.sql.*;
import org.apache.openjpa.persistence.jdbc.*;
...
Query q = em.createQuery ("select m from Magazine m where m.title = 'JDJ'");
OpenJPAQuery kq = OpenJPAPersistence.cast (q);
JDBCFetchPlan fetch = (JDBCFetchPlan) kq.getFetchPlan ();
fetch.setFetchSize (20);
fetch.setResultSetType (ResultSet.TYPE_SCROLL_INSENSITIVE);
fetch.setFetchDirection (ResultSet.FETCH_FORWARD);
fetch.setLRSSize (JDBCFetchPlan.SIZE_LAST);
List results = (List) q.getResultList ();
Default Schemaschemadefault
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
openjpa.jdbc.Schema configuration property. This property
establishes a default schema for any unqualified table names, allowing
you to leave schema names out of your mapping definitions.
The Schema property also establishes the default
schema for new tables created through OpenJPA tools, such as the mapping
tool covered in .
Schema Reflectionschemareflection
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
SchemaFactory interface to provide runtime
mapping information, and the SchemaTool
for development-time data. Each is presented below.
Schemas ListSchemasschemaschemas list
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 openjpa.jdbc.Schemas 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
<schema-name>.<table-name>. If a
table does not have a schema or you do not know its schema, list
its name as .<table-name> (notice the
preceding '.'). For example, to list the
BUSOBJS schema, the ADDRESS
table in the GENERAL schema, and the
SYSTEM_INFO table, regardless of what schema it
is in, use the string:
BUSOBJS,GENERAL.ADDRESS,.SYSTEM_INFO
Some databases are case-sensitive with respect to schema
and table names. Oracle, for example, requires names
in all upper case.
Schema FactoryschemaSchemaFactory
OpenJPA relies on the
openjpa.jdbc.SchemaFactory interface
for runtime schema information. You can control the schema factory
OpenJPA uses through the openjpa.jdbc.SchemaFactory
property. There are several built-in options to choose from:
dynamic: This is the default setting.
It is an alias for the
org.apache.openjpa.jdbc.schema.DynamicSchemaFactory. The DynamicSchemaFactory
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.
native: This is an alias for the
org.apache.openjpa.jdbc.schema.LazySchemaFactory. As persistent classes are loaded by the
application, OpenJPA reads their metadata and
object-relational mapping information. This
factory uses the java.sql.DatabaseMetaData
interface to reflect on the schema and ensure
that it is consistent with the mapping data being read.
Because the factory doesn't reflect on a table
definition until that table is mentioned by the
mapping information, we call it "lazy". Use this
factory if you want up-front validation that your mapping
metadata is consistent with the database during development.
This factory accepts the following important properties:
ForeignKeys: Set to
true to automatically read foreign key
information during schema validation.
table: This is an alias for the
org.apache.openjpa.jdbc.schema.TableSchemaFactory. 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
java.sql.DatabaseMetaData
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:
Table: The name of the table
to create to store schema information. Defaults
to OPENJPA_SCHEMA.
PrimaryKeyColumn: The name of
the table's numeric primary key column. Defaults
to ID.
SchemaColumn: The name of
the table's string column for holding the schema
definition as an XML string. Defaults to
SCHEMA_DEF.
file: This is an alias for the
org.apache.openjpa.jdbc.schema.FileSchemaFactory. This factory is a lot like the
TableSchemaFactory, 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:
File: The resource name
of the XML schema file. By default, the factory
looks for a resource called
package.schema, located in any top-level
directory of the CLASSPATH or
in the top level of any jar in your
CLASSPATH.
You can switch freely between schema factories at any time.
The XML file format used by some factories is detailed
in . As with any OpenJPA
plugin, you can can also implement your own schema factory if you
have needs not met by the existing options.
Schema Toolschemaschema toolschemaDDLDDLSQLDDLDDLDDLwith schema tool
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:
To reflect on the current database schema, optionally
translating it to an XML representation for further
manipulation.
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.
The XML format
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.
You can invoke the schema tool through the
schematool shell/bat script included in the
OpenJPA distribution, or through its Java class,
org.apache.openjpa.jdbc.schema.SchemaTool. In
addition to the universal flags of the
configuration framework, the schema tool accepts the following
command line arguments:
-ignoreErrors/-i <true/t | false/f>:
If false, an exception will
be thrown if the tool encounters any database errors.
Defaults to false.
-file/-f <stdout | output file>:
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
export or reflect actions, the named file will be used to write the exported schema XML.
If the file names a resource in the
CLASSPATH, data will be written
to that resource. Use stdout to
write to standard output. Defaults to
stdout.
-openjpaTables/-kt <true/t | false/f>:
When reflecting on the schema, whether to reflect on tables
and sequences whose names start with OPENJPA_.
Certain OpenJPA components may use such tables - for example,
the table schema factory option covered
in .
When using other actions, openjpaTables
controls whether these tables can be dropped. Defaults to
false.
-dropTables/-dt <true/t | false/f>:
Set this option to true to drop tables
that appear to be unused during retain
and refresh actions. Defaults to
true.
-dropSequences/-dsq <true/t | false/f>:
Set this option to true to drop sequences
that appear to be unused during retain
and refresh actions. Defaults to
true.
-sequences/-sq <true/t | false/f>:
Whether to manipulate sequences.
Defaults to true.
-indexes/-ix <true/t | false/f>:
Whether to manipulate indexes on existing tables.
Defaults to true.
-primaryKeys/-pk <true/t | false/f>:
Whether to manipulate primary keys on existing
tables. Defaults to true.
-foreignKeys/-fk <true/t | false/f>:
Whether to manipulate foreign keys on
existing tables. Defaults to true.
-record/-r <true/t | false/f>: Use
false to prevent writing the schema
changes made by the tool to the current
schema factory. Defaults to
true.
-schemas/-s <schema list>: A list
of schema and table names that OpenJPA should access during
this run of the schema tool. This is equivalent to setting
the openjpa.jdbc.Schemas
property for a single run.
The schema tool also accepts an -action or
-a flag. The available actions are:
add: 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.
retain: Keep all schema components in
the given XML definition, but drop the rest from the
database. This action never adds any schema components.
drop: 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.
refresh: Equivalent to
retain, then add.
build: Generate SQL to build a schema
matching the one in the given XML file. Unlike
add, 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 -file
flag to write a SQL script. This script can later be used to
recreate the schema in the XML.
reflect: Generate an XML representation
of the current database schema.
createDB: Generate SQL to re-create the
current database. This action is typically used in
conjunction with the -file flag to
write a SQL script that can be used to recreate the current
schema on a fresh database.
dropDB: Generate SQL to drop the
current database. Like createDB, this
action can be used with the -file
flag to script a database drop rather than perform it.
import: Import the given XML schema
definition into the current schema factory. Does nothing
if the factory does not store a record of the schema.
export: 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.
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.
We present some examples of schema tool usage below.
Schema Creationschemacreate with schema tool
Add the necessary schema components to the database to match
the given XML document, but don't drop any data:
schematool targetSchema.xml
SQL Scripting
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:
schematool -f script.sql targetSchema.xml
Write a SQL script that will re-create the current database:
schematool -a createDB -f script.sql
Schema Drop
Drop the current database:
schematool -a dropDB
Schema Reflectionschemareflectionwith schema tool
Write an XML representation of the current schema to file
schema.xml.
schematool -a reflect -f schema.xml
XML Schema FormatschemaXML representation
The schema tool and
schema factories 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.
<!ELEMENT schemas (schema)+>
<!ELEMENT schema (table|sequence)+>
<!ATTLIST schema name CDATA #IMPLIED>
<!ELEMENT sequence EMPTY>
<!ATTLIST sequence name CDATA #REQUIRED>
<!ATTLIST sequence initial-value CDATA #IMPLIED>
<!ATTLIST sequence increment CDATA #IMPLIED>
<!ATTLIST sequence allocate CDATA #IMPLIED>
<!ELEMENT table (column|index|pk|fk)+>
<!ATTLIST table name CDATA #REQUIRED>
<!ELEMENT column EMPTY>
<!ATTLIST column name CDATA #REQUIRED>
<!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>
<!ATTLIST column not-null (true|false) "false">
<!ATTLIST column auto-assign (true|false) "false">
<!ATTLIST column default CDATA #IMPLIED>
<!ATTLIST column size CDATA #IMPLIED>
<!ATTLIST column decimal-digits CDATA #IMPLIED>
<!-- the type-name attribute can be used when you want OpenJPA to -->
<!-- use a particular SQL type declaration when creating the -->
<!-- column. It is up to you to ensure that this type is -->
<!-- compatible with the JDBC type used in the type attribute. -->
<!ATTLIST column type-name CDATA #IMPLIED>
<!-- the 'column' attribute of indexes, pks, and fks can be used -->
<!-- when the element has only one column (or for foreign keys, -->
<!-- only one local column); in these cases the on/join child -->
<!-- elements can be omitted -->
<!ELEMENT index (on)*>
<!ATTLIST index name CDATA #REQUIRED>
<!ATTLIST index column CDATA #IMPLIED>
<!ATTLIST index unique (true|false) "false">
<!-- the 'logical' attribute of pks should be set to 'true' if -->
<!-- the primary key does not actually exist in the database, -->
<!-- but the given column should be used as a primary key for -->
<!-- O-R purposes -->
<!ELEMENT pk (on)*>
<!ATTLIST pk name CDATA #IMPLIED>
<!ATTLIST pk column CDATA #IMPLIED>
<!ATTLIST pk logical (true|false) "false">
<!ELEMENT on EMPTY>
<!ATTLIST on column CDATA #REQUIRED>
<!-- fks with a delete-action of 'none' are similar to logical -->
<!-- pks; they do not actually exist in the database, but -->
<!-- represent a logical relation between tables (or their -->
<!-- corresponding Java classes) -->
<!ELEMENT fk (join)*>
<!ATTLIST fk name CDATA #IMPLIED>
<!ATTLIST fk deferred (true|false) "false">
<!ATTLIST fk to-table CDATA #REQUIRED>
<!ATTLIST fk column CDATA #IMPLIED>
<!ATTLIST fk delete-action (cascade|default|exception|none|null) "none">
<!ELEMENT join EMPTY>
<!ATTLIST join column CDATA #REQUIRED>
<!ATTLIST join to-column CDATA #REQUIRED>
<!ATTLIST join value CDATA #IMPLIED>
<!-- unique constraint -->
<!ELEMENT unique (on)*>
<!ATTLIST unique name CDATA #IMPLIED>
<!ATTLIST unique column CDATA #IMPLIED>
<!ATTLIST unique deferred (true|false) "false">
Basic Schema
A very basic schema definition.
<schemas>
<schema>
<sequence name="S_ARTS"/>
<table name="ARTICLE">
<column name="TITLE" type="varchar" size="255" not-null="true"/>
<column name="AUTHOR_FNAME" type="varchar" size="28">
<column name="AUTHOR_LNAME" type="varchar" size="28">
<column name="CONTENT" type="clob">
</table>
<table name="AUTHOR">
<column name="FIRST_NAME" type="varchar" size="28" not-null="true">
<column name="LAST_NAME" type="varchar" size="28" not-null="true">
</table>
</schema>
</schemas>
Full Schema
Expansion of the above schema with primary keys, constraints,
and indexes, some of which span multiple columns.
<schemas>
<schema>
<sequence name="S_ARTS"/>
<table name="ARTICLE">
<column name="TITLE" type="varchar" size="255" not-null="true"/>
<column name="AUTHOR_FNAME" type="varchar" size="28">
<column name="AUTHOR_LNAME" type="varchar" size="28">
<column name="CONTENT" type="clob">
<pk column="TITLE"/>
<fk to-table="AUTHOR" delete-action="exception">
<join column="AUTHOR_FNAME" to-column="FIRST_NAME"/>
<join column="AUTHOR_LNAME" to-column="LAST_NAME"/>
</fk>
<index name="ARTICLE_AUTHOR">
<on column="AUTHOR_FNAME"/>
<on column="AUTHOR_LNAME"/>
</index>
</table>
<table name="AUTHOR">
<column name="FIRST_NAME" type="varchar" size="28" not-null="true">
<column name="LAST_NAME" type="varchar" size="28" not-null="true">
<pk>
<on column="FIRST_NAME"/>
<on column="LAST_NAME"/>
</pk>
</table>
</schema>
</schemas>