Chapter 8. Schema Information

8.1. Schema Reflection
8.1.1. Schemas List
8.1.2. Schema Factory
8.1.3. Schema Generator
8.2. Schema Tool
8.3. XML Schema Format
8.4. The SQLLine Utility

Kodo JDO stores persistent objects in relational database tables. This raises two important questions:

  1. How does Kodo JDO get information about your database schema?

  2. How do your persistent class definitions and your database schema stay synchronized?

This chapter explores the answers to these questions.

8.1. Schema Reflection

Kodo JDO needs information about your database schema for two reasons. First, it needs schema information at runtime to validate that your schema is compatible with your persistent class definitions, and to perform advanced actions like foreign key constraint analysis. Second, Kodo JDO requires schema information during development so that it can manipulate the schema to match your object model. Kodo JDO uses the SchemaFactory interface to provide runtime mapping information, and the schema generator tool for development-time data. Each is presented below.

8.1.1. Schemas List

By default, the tools and processes covered in this chapter act on all the schemas your JDBC driver can "see". You can limit the schemas and tables Kodo acts on with the kodo.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:

kodo.jdbc.Schemas: BUSOBJS,GENERAL.ADDRESS,.SYSTEM_INFO

When Kodo creates new tables, it will place them in the first schema listed.

[Note]Note

Some databases are case-sensitive with respect to schema and table names. Oracle, for example, requires names in all upper case.

8.1.2. Schema Factory

Kodo JDO relies on the kodo.jdbc.SchemaFactory interface for runtime schema information. You can control the schema factory Kodo JDO uses through the kodo.jdbc.SchemaFactory property. There are several built-in options to choose from:

  • native: This is the default schema factory, and the one recommended for most users. It is an alias for the kodo.jdbc.schema.LazySchemaFactory . As persistent classes are loaded by the application, Kodo JDO reads their JDO 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 its class "lazy".

  • dynamic: This is an alias for the kodo.jdbc.schema.DynamicSchemaFactory . The DynamicSchemaFactory is the most performant schema factory, because it does not validate mapping information against the existing schema. Instead, it always assumes all object-relational mapping information is correct, and dynamically builds up an in-memory representation of the schema from the mapping data. You may want to use this factory if your JDBC driver doesn't support the java.sql.DatabaseMetaData interface, or you trust that your mapping data and schema are always in synch. You may also want to use this schema factory to prevent validation if you use database views for certain classes. Most JDBC drivers do not report the structure of views, and so any classes mapped to views will probably fail validation.

    [Note]Note

    The dynamic schema factory cannot auto-detect foreign keys, column defaults, non-nullable columns, and other database information. This means that if the schema has any foreign keys that are not deferred, Kodo will not know to re-order SQL statements to satisfy the foreign keys contraints and some inserts will fail; in these cases, the file or native schema factory will need to be used instead.

  • db: This is an alias for the kodo.jdbc.schema.DBSchemaFactory . 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:

    • TableName: The name of the table to create to store schema information. Defaults to JDO_SCHEMA.

  • file: This is an alias for the kodo.jdbc.schema.FileSchemaFactory . This factory is a lot like the DBSchemaFactory, 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:

    • FileName: 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 Section 8.3, “XML Schema Format”. Some of the factories are configurable; see their Javadoc for details. Finally, as with any Kodo JDO plugin, you can can implement your own schema factory if you have needs not met by the existing options.

8.1.3. Schema Generator

While the schema factory provides schema information to runtime components, most development tools rely on the schema generator behind-the-scenes. The schema generator uses the JDBC driver's java.sql.DatabaseMetaData implementation to build up an internal representation of your database schema. This internal representation can then be dumped to an XML file, which in turn can be manipulated by other tools, most notably the schema tool. The XML format used by the schema generator is detailed below. Some schema factories also invoke the schema generator programmatically and directly use its Java object view of schema components.

As a user, you will rarely if ever use the schema generator directly. Should the need arise, however, you can invoke the schema generator via the schemagen shell/bat script included in the Kodo JDO distribution, or via its Java class, kodo.jdbc.schema.SchemaGenerator.

Example 8.1. Using the Schema Generator

schemagen -f schema.xml

The schema generator accepts the following flags (in addition to the universal flags discussed in the Configuration Framework chapter):

  • -indexes/-ix <true/t | false/f>: Whether to generate information about table indexes. Defaults to true.

  • -primaryKeys/-pk <true/t | false/f> : Whether to generate information about primary keys. Defaults to true.

  • -foreignKeys/-fk <true/t | false/f> : Whether to generate information about foreign keys. Defaults to true.

  • -kodoTables/-kt <true/t | false/f>: Whether to generate information about special Kodo-generated tables such as sequence tables. Defaults to false.

  • -schemas/-s <schema and table names> : A comma-separated list of schema and table names to generate information on. Each element of the list must follow the naming conventions for the kodo.jdbc.Schemas property. In fact, if this flag is omitted, it defaults to the value of the Schemas property. If the Schemas property is not defined, information for all schemas will be generated.

  • -file/-f <stdout | output file> : The name of the output file to write the XML schema definition to. If the file names a resource in the CLASSPATH, data will be written to that resource. Use stdout to write the XML to standard output. Defaults to stdout.