JDBC JDBC 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 DataSource DataSource OpenJPA connections DataSource 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: 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 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 . 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: connections pooling ExceptionAction ExceptionAction: 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. connections pooling MaxActive MaxActive: 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. connections pooling MaxIdle MaxIdle: 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. connections pooling MaxTotal MaxTotal: 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). connections pooling MaxWait MaxWait: The maximum number of milliseconds to wait for a free database connection to become available before giving up. Defaults to 3000. connections pooling MinEvictableIdleTimeMillis MinEvictableIdleTimeMillis: 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. connections pooling RollbackOnReturn RollbackOnReturn: 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. connections pooling TestOnBorrow TestOnBorrow: 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 . connections pooling TestOnReturn TestOnReturn: 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. connections pooling TestWhileIdle TestWhileIdle: Set to true to periodically validate idle database connections. connections pooling TimeBetweenEvictionRunsMillis TimeBetweenEvictionRunsMillis: The number of milliseconds between runs of the eviction thread. Defaults to -1, meaning the eviction thread will never run. connections pooling TrackParameters TrackParameters: When true, OpenJPA will track the parameters that were set for all PreparedStatement s that are executed or batched so that they can be included in error messages. Defaults to true. connections pooling ValidationSQL ValidationSQL: 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 Defaults Database SQL DB2 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
connections pooling ClosePoolSQL ClosePoolSQL: 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. connections pooling ValidationTimeout ValidationTimeout: 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). connections pooling WarningAction WarningAction: 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. connections pooling WhenExhaustedAction WhenExhaustedAction: 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 statement pooling MaxCachedStatements MaxCachedStatements: 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 DataSource s. 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. JDBC QueryTimeout QueryTimeout: 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 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. 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 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, 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 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 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 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. 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.
SQLFactory Properties SQL SQLFactory 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 statement batching BatchLimit BatchLimit: The maximum number of SQL update statements to batch together. Set to 0 to disable statement batching, or -1 for no limit. See . prepared statement batching BatchParameterLimit BatchParameterLimit: 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 statement batching SupportsUpdateCountsForBatch SupportsUpdateCountsForBatch: Whether the JDBC driver correctly returns the set of update counts when a batch statement is executed. prepared statement batching SupportsTotalCountsForBatch SupportsTotalCountsForBatch: 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. SQL union SupportsUnion SupportsUnion: Whether the database supports SQL UNIONs. SQL union SupportsUnionWithUnalignedOrdering SupportsUnionWithUnalignedOrdering: 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 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 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 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 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 Batching prepared statement batching 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 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-sensitive scroll-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. reverse unknown 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 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. 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 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 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 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)+> <!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>