3.3. Auto-Generating Classes from a Schema

Table of Contents

3.3.1. Schema File DTD

Kodo JDO now includes a preview release of our upcoming reverse mapping tool. The reverse mapping tool generates persistent class definitions, complete with JDO metadata and Kodo mapping extensions, from an existing database schema. The tool is currently in its beta stages of development; bug reports are very much appreciated. The reverse mapping tool has been tested with the following databases:

To use the reverse mapping tool, follow the steps below:

  1. Set the com.solarmetric.kodo.impl.jdbc.Schemas configuration property to a comma-separated list of the names of the target database schemas. If you do not use use explicit database schemas, you can skip this step (in this case Kodo JDO will attempt to filter out system tables on its own; for example under Oracle it filters all tables with a schema of MDSYS, SYS, or SYSTEM).

    Note that some databases require schema names to be in a certain case. If you are using Oracle, for example, your schema names must be in all upper case, regardless of what case you used when creating the schema.

  2. Use the R&D schema generator to export your current schema to an XML schema file. The R&D schema generator can be run via the included rd-schemagen script or through its Java class, com.solarmetric.rd.kodo.impl.jdbc.schema.SchemaGenerator. For example:

    rd-schemagen -properties myprops.properties -file schema.xml
    				

    You can limit the schemas and/or tables the schema generator looks at by listing the target schemas and tables on the command line. To target a schema, list its name. To target a table, list its full name in the form <schema-name>.<table-name>. If a target table does not have a schema or you do not know its schema, list its name as .<table-name>. The example below will generate XML for the entire BUSOBJS schema, the ADDRESS table in the GENERAL schema, and the SYSTEM_INFO table, regardless of what schema it is in (or it may not have a schema).

    rd-schemagen -properties myprops.properties -file schema.xml BUSOBJS
    GENERAL.ADDRESS .SYSTEM_INFO
    				

  3. Examine the generated schema file. JDBC drivers often provide incomplete or faulty metadata, in which case the file will not exactly match the actual schema. Alter the XML file to match the true schema. The DTD for the schema file is given here.

    After fixing any errors in the schema file, modify the XML to include foreign keys between all related tables. The schema generator will have automatically detected existing foreign key constraints; many schemas, however, do not employ database foreign keys for every table relation. By manually adding any missing foreign keys, you will give the reverse mapping tool the information it needs to reflect the proper relations between the persistent classes it creates.

  4. Run the reverse mapping tool on the finished schema file. (If you do not supply the schema file to reverse map, the tool will run directly against the schema in the database). The tool can be run via the included rd-reversemappingtool script, or through its Java class, com.solarmetric.rd.kodo.impl.jdbc.meta.ReverseMappingTool. In addition to the standard configuration flags accepted by all Kodo JDO tools, the reverse mapping tool recognizes the following command line flags:

    • -package <package name>: The package name of the generated classes. If no package name is given, the generated code will not contain package declarations.

    • -file <output directory>: The path to the directory to output all generated code and metadata to. Defaults to the current directory.

    • -useSchemaName <true | false> : Set this flag to true to include the schema as well as table name in the name of each generated class. This can be useful when dealing with multiple schemas with same-named tables.

    • -useForeignKeyName <true | false> : Set this flag to true if you woule like field names for relations to be based on the database foreign key name. By default, relation field names are derived from the name of the related class.

    • -inheritance <true | false>: Set this flag to false if you do not want the tool to create inheritance relationships based on foreign key information. Any foreign keys that would have indicated inheritance will be translated as 1-1 relationships instead.

    • -nullableAsObject <true | false> : By default, all non-foreign key columns are mapped to primitives. Set this flag to true to generate primitive wrapper fields instead for columns that allow null values.

    • -primaryKeyOnJoin <true | false> : The standard reverse mapping tool behavior is to map all tables with primary keys to persistent classes. If your schema has primary keys on many-many join tables as well, set this flag to true to avoid creating classes for those tables.

    • -metadata <package | class>: Whether to write a single package-level JDO metadata file, or to write a JDO metadata file per generated class. Defaults to package.

    Note

    If you are using Kodo's JBuilder integration features, make sure to specify the -metadata class flag to write a separate JDO metadata file per class.

    Standard usage example:

    rd-reversemappingtool -properties myprops.properties -package com.xyz.jdo schema.xml
    				

    Running the tool will generate .java files for each generated class, package-level or per-class .jdo files, depending on the -metadata flag, a <package-name>.schema file, and a <package-name>.mapping file. The schema file is there to show you what portion of the schema was mapped; it serves no other purpose and can be deleted if desired. The mapping file contains the O/R mapping information for the generated classes. Mapping files like these will be offered as an optional alternative to O/R metadata extensions in a future version of Kodo JDO. For now, you must import the mapping information into Kodo JDO metadata extensions.

  5. To import the generated O/R mapping information into metadata extensions, run the R&D import tool on the mapping file. The tool can be invoked via the included rd-importtool script or through its Java class, com.solarmetric.rd.kodo.impl.jdbc.meta.compat.ImportTool. Make sure to compile the generated classes before the import:

    javac *.java
    rd-importtool -properties myprops.properties jdo.mapping
    				

    You can now delete the mapping file if desired.

  6. Examine the generated classes and metadata, and modify them as necessary.

3.3.1. Schema File DTD

<!ELEMENT schemas (schema)+>
<!ELEMENT schema (table)*>
<!ATTLIST schema name 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 default CDATA #IMPLIED>
<!ATTLIST column size CDATA #IMPLIED>
<!ATTLIST column decimal-digits CDATA #IMPLIED>

<!-- the 'column' attribute of indexes, pks, and fks can be used -->
<!-- when the element has only one column (or for foriegn keys,  -->
<!-- only one local column); in these cases the on/join child    -->
<!-- elements can be ommitted                                    -->
<!ELEMENT index (on)*>
<!ATTLIST index name CDATA #REQUIRED>
<!ATTLIST index column CDATA #IMPLIED>
<!ATTLIST index unique (true|false) "false">
<!ELEMENT pk (on)*>
<!ATTLIST pk name CDATA #IMPLIED>
<!ATTLIST pk column CDATA #IMPLIED>
<!ELEMENT on EMPTY>
<!ATTLIST on column CDATA #REQUIRED>
<!ELEMENT fk (join)*>
<!ATTLIST fk name CDATA #IMPLIED>
<!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>