JDBC
JDBC
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.
Using the OpenJPA DataSource
DataSource
OpenJPA
connections
DataSource
OpenJPA includes its own simple javax.sql.DataSource
implementation. If you choose to use OpenJPA's DataSource
, then you must specify the following properties:
ConnectionUserName
openjpa.ConnectionUserName: The JDBC user name for
connecting to the database.
ConnectionPassword
openjpa.ConnectionPassword: The JDBC password for the above
user.
ConnectionURL
openjpa.ConnectionURL: The JDBC URL for the database.
ConnectionDriverName
openjpa.ConnectionDriverName: The JDBC driver class.
To configure advanced features, use the following optional
properties. The syntax of these property strings follows the syntax of OpenJPA
plugin parameters described in .
ConnectionProperties
openjpa.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.
ConnectionFactoryProperties
openjpa.ConnectionFactoryProperties: OpenJPA's built-in
DataSource allows you to set the following options via
this plugin string:
JDBC
QueryTimeout
QueryTimeout: The maximum number of seconds the JDBC driver
will wait for a statement to execute.
SQL
PrettyPrint
PrettyPrint: Boolean indicating whether to pretty-print
logged SQL statements.
SQL
PrettyPrintLineLength
PrettyPrintLineLength: The maximum number of characters in
each pretty-printed SQL line.
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="PrettyPrint=true, PrettyPrintLineLength=80"/>
Using a Third-Party DataSource
DataSource
third 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.
The 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 features 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 DataSources
DataSource
managed
DataSource
XA
ConnectionFactoryMode
Certain application servers automatically enlist their DataSource
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
DataSource is managed by the application server, use the
jta-data-source element of your
persistence.xml file or 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 using the non-jta-data-source
persistence.xml element, or OpenJPA's various
"2" connection properties, such as openjpa.ConnectionFactory2Name
or openjpa.Connection2DriverName. These
properties are outlined in .
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"/>
</properties>
Runtime Access to DataSource
connections
accessing DataSource
JDBC
accessing 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 Support
DBDictionary
relational database
OpenJPA support
DBDictionary
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 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 Access
access: Dictionary for Microsoft Access. This is an alias
for the
org.apache.openjpa.jdbc.sql.AccessDictionary
class.
DB2
db2: Dictionary for IBM's DB2 database. This is an alias for
the org.apache.openjpa.jdbc.sql.DB2Dictionary class.
Derby
derby: Dictionary for the Apache Derby database. This is an
alias for the
org.apache.openjpa.jdbc.sql.DerbyDictionary class.
Empress
empress: Dictionary for Empress database This is an alias
for the
org.apache.openjpa.jdbc.sql.EmpressDictionary
class.
FoxPro
foxpro: Dictionary for Microsoft Visual FoxPro. This is an
alias for the
org.apache.openjpa.jdbc.sql.FoxProDictionary
class.
Hypersonic SQL
hsql: Dictionary for the Hypersonic SQL database. This is an
alias for the
org.apache.openjpa.jdbc.sql.HSQLDictionary class.
Informix
informix: Dictionary for the Informix database. This is an
alias for the
org.apache.openjpa.jdbc.sql.InformixDictionary
class.
JDataStore
jdatastore: Dictionary for Borland JDataStore. This is an
alias for the
org.apache.openjpa.jdbc.sql.JDataStoreDictionary
class.
MySQL
mysql: Dictionary for the MySQL database. This is an alias
for the
org.apache.openjpa.jdbc.sql.MySQLDictionary
class.
Oracle
oracle: Dictionary for Oracle. This is an alias for the
org.apache.openjpa.jdbc.sql.OracleDictionary
class.
Pointbase
pointbase: Dictionary for Pointbase Embedded database. This
is an alias for the
org.apache.openjpa.jdbc.sql.PointbaseDictionary
class.
PostgreSQL
postgres: Dictionary for PostgreSQL. This is an alias for
the org.apache.openjpa.jdbc.sql.PostgresDictionary
class.
SQLServer
sqlserver: Dictionary for Microsoft's SQLServer database.
This is an alias for the
org.apache.openjpa.jdbc.sql.SQLServerDictionary
class.
Sybase
sybase: 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.
JDBC
DriverVendor
DriverVendor: 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.
SQL
CatalogSeparator
CatalogSeparator: The string the database uses to delimit
between the schema name and the table name. This is typically "."
, which is the default.
DDL
CreatePrimaryKeys
CreatePrimaryKeys: If false, then do not
create database primary keys for identifiers. Defaults to true
.
DDL
ConstraintNameMode
ConstraintNameMode: 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
.
DDL
MaxTableNameLength
MaxTableNameLength: The maximum number of characters in a
table name. Defaults to 128.
DDL
MaxColumnNameLength
MaxColumnNameLength: The maximum number of characters in a
column name. Defaults to 128.
DDL
MaxConstraintNameLength
MaxConstraintNameLength: The maximum number of characters in
a constraint name. Defaults to 128.
DDL
MaxIndexNameLength
indexes
MaxIndexNameLength
MaxIndexNameLength: The maximum number of characters in an
index name. Defaults to 128.
DDL
MaxAutoAssignNameLength
MaxAutoAssignNameLength: 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.
indexes
MaxIndexesPerTable
MaxIndexesPerTable: The maximum number of indexes that can
be placed on a single table. Defaults to no limit.
foreign keys
SupportsForeignKeys
SupportsForeignKeys: Whether the database supports foreign
keys. Defaults to true.
SupportsTimestampNanos
SupportsTimestampNanos: Whether the database supports nanoseconds with TIMESTAMP columns. Defaults to true.
unique constraints
SupportsUniqueConstraints
SupportsUniqueConstraints: Whether the database supports
unique constraints. Defaults to true.
foreign keys
SupportsDeferredConstraints
SupportsDeferredConstraints: Whether the database supports
deferred constraints. Defaults to true.
foreign keys
SupportsRestrictDeleteAction
SupportsRestrictDeleteAction: Whether the database supports
the RESTRICT foreign key delete action. Defaults to true.
foreign keys
SupportsCascadeDeleteAction
SupportsCascadeDeleteAction: Whether the database supports
the CASCADE foreign key delete action. Defaults to true.
foreign keys
SupportsNullDeleteAction
SupportsNullDeleteAction: Whether the database supports the
SET NULL foreign key delete action. Defaults to true.
foreign keys
SupportsDefaultDeleteAction
SupportsDefaultDeleteAction: Whether the database supports
the SET DEFAULT foreign key delete action. Defaults to true.
DDL
SupportsAlterTableWithAddColumn
SupportsAlterTableWithAddColumn: Whether the database
supports adding a new column in an ALTER TABLE statement. Defaults to
true.
DDL
SupportsAlterTableWithDropColumn
SupportsAlterTableWithDropColumn: Whether the database
supports dropping a column in an ALTER TABLE statement. Defaults to
true.
SQL
ReservedWords
ReservedWords: A comma-separated list of reserved words for
this database, beyond the standard SQL92 keywords.
schema
reflection
SystemTables
SystemTables: A comma-separated list of table names that
should be ignored.
schema
reflection
SystemSchemas
SystemSchemas: A comma-separated list of schema names that
should be ignored.
schema
reflection
SchemaCase
SchemaCase: 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.
connections
ValidationSQL
SQL
ValidationSQL
ValidationSQL: The SQL used to validate that a connection is
still in a valid state. For example, " SELECT SYSDATE FROM DUAL
" for Oracle.
connections
InitializationSQL
SQL
InitializationSQL
InitializationSQL: A piece of SQL to issue against the
database whenever a connection is retrieved from the DataSource
.
joins
JoinSyntax
JoinSyntax: The SQL join syntax to use in select statements.
See .
joins
CrossJoinClause
CrossJoinClause: The clause to use for a cross join
(cartesian product). Defaults to CROSS JOIN.
joins
InnerJoinClause
InnerJoinClause: The clause to use for an inner join.
Defaults to INNER JOIN.
joins
OuterJoinClause
OuterJoinClause: The clause to use for an left outer join.
Defaults to LEFT OUTER JOIN.
joins
RequiresConditionForCrossJoin
RequiresConditionForCrossJoin: 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.
SQL
ToUpperCaseFunction
ToUpperCaseFunction: SQL function call for for converting a
string to upper case. Use the token {0} to represent the
argument.
SQL
ToLowerCaseFunction
ToLowerCaseFunction: Name of the SQL function for converting
a string to lower case. Use the token {0} to represent the
argument.
SQL
StringLengthFunction
StringLengthFunction: Name of the SQL function for getting
the length of a string. Use the token {0} to represent the
argument.
SQL
SubstringFunctionName
SubstringFunctionName: Name of the SQL function for getting
the substring of a string.
SQL
DistinctCountColumnSeparator
DistinctCountColumnSeparator: 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.
SQL
ForUpdateClause
locking
ForUpdateClause
ForUpdateClause: The clause to append to SELECT
statements to issue queries that obtain pessimistic locks. Defaults
to FOR UPDATE.
SQL
TableForUpdateClause
locking
TableForUpdateClause
TableForUpdateClause: The clause to append to the end of
each table alias in queries that obtain pessimistic locks. Defaults to null.
locking
SupportsSelectForUpdate
SupportsSelectForUpdate: If true, then the database supports
SELECT statements with a pessimistic locking clause. Defaults
to true.
locking
SupportsLockingWithDistinctClause
SupportsLockingWithDistinctClause: If true, then the
database supports FOR UPDATE select clauses with
DISTINCT clauses.
locking
SupportsLockingWithOuterJoin
SupportsLockingWithOuterJoin: If true, then the database
supports FOR UPDATE select clauses with outer join queries.
locking
SupportsLockingWithInnerJoin
SupportsLockingWithInnerJoin: If true, then the database
supports FOR UPDATE select clauses with inner join queries.
locking
SupportsLockingWithMultipleTables
SupportsLockingWithMultipleTables: If true, then the
database supports FOR UPDATE select clauses that select from
multiple tables.
locking
SupportsLockingWithOrderClause
SupportsLockingWithOrderClause: If true, then the database
supports FOR UPDATE select clauses with ORDER BY
clauses.
locking
SupportsLockingWithSelectRange
SupportsLockingWithSelectRange: 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.
locking
SimulateLocking
SimulateLocking: 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.
JDBC
QueryTimeout
SupportsQueryTimeout
SupportsQueryTimeout: If true, then the JDBC driver supports
calls to java.sql.Statement.setQueryTimeout.
aggregates
having
SupportsHaving
SupportsHaving: Whether this database supports HAVING
clauses in selects.
Query
result range
SupportsSelectStartIndex
SupportsSelectStartIndex: Whether this database can create a
select that skips the first N results.
Query
result range
SupportsSelectEndIndex
SupportsSelectEndIndex: Whether this database can create a
select that is limited to the first N results.
SQL
SupportsSubselect
JPQL
subselects
SupportsSubselect
SupportsSubselect: Whether this database supports subselects
in queries.
SQL
RequiresAliasForSubselect
JPQL
subselects
RequiresAliasForSubselect
RequiresAliasForSubselect: 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 fields
StorageLimitationsFatal
StorageLimitationsFatal: 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 fields
StoreLargeNumbersAsStrings
StoreLargeNumbersAsStrings: 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 fields
StoreCharsAsNumbers
StoreCharsAsNumbers: Set this property to false
to store Java char fields as CHAR
values rather than numbers. Defaults to true.
BLOB
UseGetBytesForBlobs
UseGetBytesForBlobs: If true, then
ResultSet.getBytes will be used to obtain blob data rather than
ResultSet.getBinaryStream.
BLOB
UseGetObjectForBlobs
UseGetObjectForBlobs: If true, then
ResultSet.getObject will be used to obtain blob data rather than
ResultSet.getBinaryStream.
BLOB
UseSetBytesForBlobs
UseSetBytesForBlobs: If true, then
PreparedStatement.setBytes will be used to set blob data, rather
than PreparedStatement.setBinaryStream.
CLOB
UseGetStringForClobs
UseGetStringForClobs: If true, then
ResultSet.getString will be used to obtain clob data rather than
ResultSet.getCharacterStream.
CLOB
UseSetStringForClobs
UseSetStringForClobs: If true, then
PreparedStatement.setString will be used to set clob data, rather
than PreparedStatement.setCharacterStream.
DDL
CharacterColumnSize
CharacterColumnSize: The default size of varchar
and char columns. Typically 255.
DDL
ArrayTypeName
ArrayTypeName: The overridden default column type for
java.sql.Types.ARRAY. This is only used when the schema is
generated by the mappingtool.
DDL
BigintTypeName
BigintTypeName: The overridden default column type for
java.sql.Types.BIGINT. This is only used when the schema is
generated by the mappingtool.
DDL
BinaryTypeName
BinaryTypeName: The overridden default column type for
java.sql.Types.BINARY. This is only used when the schema is
generated by the mappingtool.
DDL
BitTypeName
BitTypeName: The overridden default column type for
java.sql.Types.BIT. This is only used when the schema is generated by
the mappingtool.
DDL
BlobTypeName
BLOB
BlobTypeName
BlobTypeName: The overridden default column type for
java.sql.Types.BLOB. This is only used when the schema is
generated by the mappingtool.
DDL
CharTypeName
CharTypeName: The overridden default column type for
java.sql.Types.CHAR. This is only used when the schema is
generated by the mappingtool.
DDL
ClobTypeName
CLOB
ClobTypeName
ClobTypeName: The overridden default column type for
java.sql.Types.CLOB. This is only used when the schema is
generated by the mappingtool.
DDL
DateTypeName
DateTypeName: The overridden default column type for
java.sql.Types.DATE. This is only used when the schema is
generated by the mappingtool.
DDL
DecimalTypeName
DecimalTypeName: The overridden default column type for
java.sql.Types.DECIMAL. This is only used when the schema is
generated by the mappingtool.
DDL
DistinctTypeName
DistinctTypeName: The overridden default column type for
java.sql.Types.DISTINCT. This is only used when the schema
is generated by the mappingtool.
DDL
DoubleTypeName
DoubleTypeName: The overridden default column type for
java.sql.Types.DOUBLE. This is only used when the schema is
generated by the mappingtool.
DDL
FloatTypeName
FloatTypeName: The overridden default column type for
java.sql.Types.FLOAT. This is only used when the schema is
generated by the mappingtool.
DDL
IntegerTypeName
IntegerTypeName: The overridden default column type for
java.sql.Types.INTEGER. This is only used when the schema is
generated by the mappingtool.
DDL
JavaObjectTypeName
JavaObjectTypeName: The overridden default column type for
java.sql.Types.JAVAOBJECT. This is only used when the schema
is generated by the mappingtool.
DDL
LongVarbinaryTypeName
LongVarbinaryTypeName: The overridden default column type
for java.sql.Types.LONGVARBINARY. This is only used when the
schema is generated by the mappingtool.
DDL
LongVarcharTypeName
LongVarcharTypeName: The overridden default column type for
java.sql.Types.LONGVARCHAR. This is only used when the
schema is generated by the mappingtool.
DDL
NullTypeName
NullTypeName: The overridden default column type for
java.sql.Types.NULL. This is only used when the schema is
generated by the mappingtool.
DDL
NumericTypeName
NumericTypeName: The overridden default column type for
java.sql.Types.NUMERIC. This is only used when the schema is
generated by the mappingtool.
DDL
OtherTypeName
OtherTypeName: The overridden default column type for
java.sql.Types.OTHER. This is only used when the schema is
generated by the mappingtool.
DDL
RealTypeName
RealTypeName: The overridden default column type for
java.sql.Types.REAL. This is only used when the schema is
generated by the mappingtool.
DDL
RefTypeName
RefTypeName: The overridden default column type for
java.sql.Types.REF. This is only used when the schema is generated by
the mappingtool.
DDL
SmallintTypeName
SmallintTypeName: The overridden default column type for
java.sql.Types.SMALLINT. This is only used when the schema
is generated by the mappingtool.
DDL
StructTypeName
StructTypeName: The overridden default column type for
java.sql.Types.STRUCT. This is only used when the schema is
generated by the mappingtool.
DDL
TimeTypeName
TimeTypeName: The overridden default column type for
java.sql.Types.TIME. This is only used when the schema is
generated by the mappingtool.
DDL
TimestampTypeName
TimestampTypeName: The overridden default column type for
java.sql.Types.TIMESTAMP. This is only used when the schema
is generated by the mappingtool.
DDL
TinyintTypeName
TinyintTypeName: The overridden default column type for
java.sql.Types.TINYINT. This is only used when the schema is
generated by the mappingtool.
DDL
VarbinaryTypeName
VarbinaryTypeName: The overridden default column type for
java.sql.Types.VARBINARY. This is only used when the schema
is generated by the mappingtool.
DDL
VarcharTypeName
VarcharTypeName: The overridden default column type for
java.sql.Types.VARCHAR. This is only used when the schema is
generated by the mappingtool.
schema
UseSchemaName
UseSchemaName: If false, then avoid
including the schema name in table name references. Defaults to true
.
schema
reflection
TableTypes
TableTypes: 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".
schema
reflection
SupportsSchemaForGetTables
SupportsSchemaForGetTables: If false, then the database
driver does not support using the schema name for schema reflection on table
names.
schema
reflection
SupportsSchemaForGetColumns
SupportsSchemaForGetColumns: If false, then the database
driver does not support using the schema name for schema reflection on column
names.
schema
reflection
SupportsNullTableForGetColumns
SupportsNullTableForGetColumns: 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.
schema
reflection
SupportsNullTableForGetPrimaryKeys
SupportsNullTableForGetPrimaryKeys: 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.
schema
reflection
SupportsNullTableForGetIndexInfo
SupportsNullTableForGetIndexInfo: 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.
schema
reflection
SupportsNullTableForGetImportedKeys
SupportsNullTableForGetImportedKeys: 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.
schema
reflection
UseGetBestRowIdentifierForPrimaryKeys
UseGetBestRowIdentifierForPrimaryKeys: If true, then
metadata queries will use DatabaseMetaData.getBestRowIdentifier
to obtain information about primary keys, rather than
DatabaseMetaData.getPrimaryKeys.
schema
reflection
RequiresAutoCommitForMetaData
RequiresAutoCommitForMetadata: If true, then the JDBC driver
requires that autocommit be enabled before any schema interrogation operations
can take place.
persistent fields
automatic field values
AutoAssignClause
AutoAssignClause: 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.
DDL
AutoAssignTypeName
persistent fields
automatic field values
AutoAssignTypeName
AutoAssignTypeName: 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 fields
automatic field values
LastGeneratedKeyQuery
LastGeneratedKeyQuery: 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.
Sequence
NextSequenceQuery
NextSequenceQuery: 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 Properties
MySQL
DBDictionary
The mysql dictionary also understands the following
properties:
MySQL
DriverDeserializesBlobs
DriverDeserializesBlobs: 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.
MySQL
TableType
TableType: The MySQL table type to use when creating tables.
Defaults to innodb.
MySQL
UseClobs
UseClobs: Some older versions of MySQL do not handle clobs
correctly. To enable clob functionality, set this to true. Defaults to
false.
OracleDictionary Properties
Oracle
DBDictionary
The oracle dictionary understands the following additional
properties:
Oracle
UseTriggersForAutoAssign
persistent fields
automatic field values
UseTriggersForAutoAssign
UseTriggersForAutoAssign: 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
.
Oracle
AutoAssignSequenceName
persistent fields
automatic field values
AutoAssignSequenceName
AutoAssignSequenceName: 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>".
Oracle
MaxEmbeddedBlobSize
BLOB
MaxEmbeddedBlobSize
MaxEmbeddedBlobSize: 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.
Oracle
MaxEmbeddedClobSize
CLOB
MaxEmbeddedClobSize
MaxEmbeddedClobSize: 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.
Setting the Transaction Isolation
transactions
isolation
JDBC
transaction isolation
TransactionIsolation
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 Syntax
joins
syntax options
SQL
join 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 Databases
relational database
accessing 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 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.
Configuring the Use of JDBC Connections
connections
usage
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 .
flush
automatic
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 flush
no flush
no flush
no flush
IgnoreChanges = false; no tx active
no flush
no flush
no flush
no flush
IgnoreChanges = false; datastore tx active
no flush
flush
flush
flush
IgnoreChanges = false; optimistic tx active
no flush
flush
no flush unless flush has already been invoked
flush
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 connection retain mode
Map props = new HashMap();
props.put("openjpa.ConnectionRetainMode", "always");
EntityManager em = emf.createEntityManager(props);
Large Result Sets
large result sets
JDBC
large result sets
large 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:
FetchBatchSize
openjpa.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 = q.getResultList();
Default Schema
schema
default
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 Reflection
schema
reflection
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 List
Schemas
schema
schemas 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 Factory
schema
SchemaFactory
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.
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 Tool
schema
schema tool
schema
DDL
DDL
SQL
DDL
DDL
DDL
with 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 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/-ot <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 Creation
schema
create with schema tool
Add the necessary schema components to the database to match the given XML
document, but don't drop any data:
java org.apache.openjpa.jdbc.schema.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:
java org.apache.openjpa.jdbc.schema.SchemaTool -f script.sql targetSchema.xml
Write a SQL script that will re-create the current database:
java org.apache.openjpa.jdbc.schema.SchemaTool -a createDB -f script.sql
Schema Drop
Drop the current database:
java org.apache.openjpa.jdbc.schema.SchemaTool -a dropDB
Schema Reflection
schema
reflection
with schema tool
Write an XML representation of the current schema to file schema.xml
.
java org.apache.openjpa.jdbc.schema.SchemaTool -a reflect -f schema.xml
XML Schema Format
schema
XML 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|unique)+>
<!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>