5.6. Auto-Generating Classes from a Schema
Prev | Chapter 5. Persistent Classes | Next

## 5.6. Auto-Generating Classes from a Schema

Kodo JDO includes a reverse mapping tool for generating persistent class definitions, complete with JDO metadata and object-relational mapping data, from an existing database schema. You do not have to use the reverse mapping tool to access an existing schema; you are free to write your classes and mapping information by hand. The reverse mapping tool, however, can give you an excellent starting point from which to grow your persistent classes.

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

1. Use the schema generator to export your current schema to an XML schema file. You can skip this step and the next step if you want to run the reverse mapping tool directly against the database schema.

   Example 5.13. Using the Schema Generator

       schemagen -f schema.xml

2. 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 XML format for the schema file is described in Section 8.3, “XML Schema Format”.

   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.

3. 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 `reversemappingtool` script, or through its Java class, `kodo.jdbc.meta.ReverseMappingTool` .

   Example 5.14. Using the Reverse Mapping Tool

       reversemappingtool -pkg com.xyz -d ~/src -cp customizer.properties schema.xml

   In addition to the standard configuration flags, including code formatting options, the reverse mapping tool recognizes the following command line arguments:

   - `-schemas/-s <schema and table names>` : A comma-separated list of schema and table names to reverse map, if no XML schema file is supplied. 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, all schemas will be reverse-mapped.

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

   - `-directory/-d <output directory>` : The path to the directory to output all generated code and metadata to. If the directory does not match the package of a class, the package structure will be created beneath this directory. Defaults to the current directory.

   - `-useSchemaName/-sn <true/t | false/f>` : 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/-fkn <true/t | false/f>`: Set this flag to `true` if you would 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.

   - `-nullableAsObject/-no <true/t | false/f>` : 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.

   - `-blobAsObject/-bo <true/t | false/f>` : By default, all binary columns are mapped to `byte[]` fields. Set this flag to `true` to map them to `Object` fields instead. Note that whem mapped this way, the column is presumed to contain a serialized Java object.

   - `-primaryKeyOnJoin/-pkj <true/t | false/f>` : 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.

   - `-oneToManyRelations/-omr <true/t | false/f>`: Set to `false` to prevent the creation of inverse 1-many relations for every 1-1 relation detected.

   - `-useDatastoreIdentity/-ds <true/t | false/f>`: Set to `true` to use datastore JDO identity for tables that have single numeric primary key columns. The tool typically uses application identity for all generated classes.

   - `-innerAppId/-inn <true/t | false/f>`: Set to `true` to have any generated application identity classes be created as static inner classes within the persistent classes. Defaults to `false`.

   - `-metadata/-md <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`.

   - `-customizerClass/-cc <class name>` : The full class name of a `kodo.jdbc.meta.ReverseCustomizer` customization plugin. If you do not specify a reverse customizer of your own, the system defaults to a `PropertiesReverseCustomizer` . This customizer allows you to specify simple customization properties in the properties file given with the `-customizerProperties` flag below. We present the available property keys below.

   - `-customizerProperties/-cp <properties file or resource>`: The path or resource name of a properties file to pass to the reverse customizer on initialization.

   - `-customizer./-c.<property name> <property value>`: The given property name will be matched with the corresponding Java bean property in the specified reverse customizer, and set to the given value.

   - `-typeMap/-typ <type mapping>`: A string that specifies the default Java classes to generate for each SQL type that is seen in the schema. The format is `SQLTYPE1=JavaClass1,SQLTYPE2=JavaClass2`. The SQL type name first looks for a customization based on `SQLTYPE(SIZE,PRECISION)`, then `SQLTYPE(SIZE)`, then `SQLTYPE(SIZE,PRECISION)`. So if a column whose type name is `CHAR` is found, it will first look for the `CHAR(50,0)` type name specification, then it will look for `CHAR(50)`, and finally it will just look for `CHAR`. For example, to generate a char array for every `CHAR` column whose size is exactly 50, and to generate a `short` for every type name of `INTEGER`, you might specify: `CHAR(50)=char[],INTEGER=short`. Note that since various databases report different type names differently, one database's type name specification might not work for another database. Enable `TRACE` level logging on the `MetaData` channel to track which type names Kodo is examining.

   Running the tool will generate `.java` files for each generated class and its application identity class, package-level or per-class `.jdo` files, depending on the `-metadata` flag, and package-level or per-class `.mapping` files, depending on the same flag.

4. Examine the generated class, metadata, and mapping information, and modify it as necessary. Information on object-relational mapping in Kodo JDO is available in Chapter 7, Object-Relational Mapping. Remember that the reverse mapping tool only provides a starting point, and you are free to make whatever modifications you want to the code it generates.

   After you are satisfied with the generated classes and their mappings, you should first compile them with `javac`, `jikes`, or your favorite Java compiler. Make sure the classes and their JDO metadata are located in the directory corresponding to the `-package` flag you gave the reverse mapping tool.

   Finally, use the mapping tool to import the object-relational mapping data in the mapping files into the mapping factory you have chosen to use. Note that if you are using the default `FileMappingFactory`, you can simply leave the mapping file(s) in place, without importing them.

   Example 5.15. Using the Mapping Tool

       jikes *.java
       mappingtool -a import xyz.mapping

Your persistent classes are now ready to access your existing schema. Remember to enhance them before use.

### 5.6.1. Customizing Reverse Mapping

The reverse mapping process can be customized with the `kodo.jdbc.meta.ReverseCustomizer` plugin interface. See the class Javadoc for details on the hooks that this interface provides. Specify the concrete plugin implementation to use with the `-customizerClass/-cc` command-line flag, described in the preceding section.

By default, the reverse mapping tool uses a `kodo.jdbc.meta.PropertiesReverseCustomizer` . This customizer allows you to perform relatively simple customizations through the properties file named with the `-customizerProperties` tool flag. The customizer recognizes the following properties:

- `<class name>.rename <new class name>` : Override the given tool-generated class name with a new value. Use full class names, including package. You are free to rename a class to a new package. Specify a value of `none` to reject the class and leave the corresponding table unmapped.

- `<class name>.identity <datastore | identity class name>`: Set this property to `datastore` to use datastore identity for the named class, rather than the default application identity. Any value other than `datastore` will be considered a new class name for the generated application identity class. Give full class names, including package. You are free to change the package of the identity class this way. If the persistent class has been renamed, use the new class name for this property key. Remember that datastore identity requires a table with a single numeric primary key column.

- `<class name>.<field name>.rename <new field name>`: Override the tool-generated field name with the given one. Use the field owner's full class name in the property key. If the field owner's class was renamed, use the new class name. The property value should be the new field name, without the preceding class name. Use a value of `none` to reject the generated mapping and remove the field from the class.

- `<class name>.<field name>.type <field type>`: The type to give the named field. Use full class names. If the field or the field's owner class has been renamed, use the new name.

- `<class name>.<field name>.value` : The initial value for the named field. The given string will be placed as-is in the generated Java code, so be sure to add quotes to strings, etc. If the field or the field's owner class has been renamed, use the new name.

- `CustomClassMappings`: A comma-separated list of custom class mapping class names to use in reverse mapping.

- `CustomFieldMappings`: A comma-separated list of custom field mapping class names to use in reverse mapping. As these mappings will run before Kodo's default mappings, care must be taken to ensure that only schema components desired to be custom-mapped are used.

- `CustomClassIndicators`: A comma-separated list of custom class indicator class names to use in reverse mapping. As these indicators will run before Kodo's default mappings, care must be taken to ensure that only schema components desired to be custom-mapped are used.

- `CustomVersionIndicators`: A comma-separated list of custom version indicator class names to use in reverse mapping. As these indicators will run before Kodo's default mappings, care must be taken to ensure that only schema components desired to be custom-mapped are used.

All property keys are optional; if not specified, the customizer keeps the default value generated by the reverse mapping tool.

Example 5.16. Customizing Reverse Mapping with Properties

    reversemappingtool -pkg com.xyz -cp custom.properties schema.xml

Example `custom.properties`:

    com.xyz.TblMagazine.rename:             com.xyz.Magazine
    com.xyz.TblArticle.rename:              com.xyz.Article
    com.xyz.TblPubCompany.rename:           com.xyz.pub.Company
    com.xyz.TblSysInfo.rename:              none

    com.xyz.Magazine.allArticles.rename:    articles
    com.xyz.Magazine.articles.type:         java.util.Collection
    com.xyz.Magazine.articles.value:        new TreeSet()
    com.xyz.Magazine.identity:              datastore

    com.xyz.pub.Company.identity:           com.xyz.pub.CompanyId

Your Kodo download includes the `PropertiesReverseCustomizer` source code. You can use this code as an example when writing your own customization class.

Prev | Up | Next
5.5. Enhancement | Home | 5.7. Persistent Class List