4.5. Examples

The examples below show extensions being used to map persistent classes to an existing schema. Remember, however, that you are free to let Kodo auto-generate the schema. In this case, you might still use a few extensions, but only to specify inverses for one-to-many relations, turn on ordering in collection or array fields, and customize the names of a few tables and columns in the event of naming conflicts.

Example 4.1. Mapping Classes to an Existing Schema

For the purpose of this example, assume the following tables exist:

PERSON
|========================================|
| PK  | NAME      | SSNUM       | MGR    |
|========================================|
| 1   | john      | 123-45-6789 | 3      |
| 2   | fred      | 987-65-4321 | 3      |
| 3   | alice     | 111-22-3333 | NULL   |
|                 ...                    |
|========================================|

PROJECT
|============================================|
| PK  | START_DATE  | END_DATE  | CODE_NAME  |
|============================================|
| 1   | 10 25 2000  | NULL      | 2.0a1      |
| 2   | 01 10 2001  | 01 31 2001| TestPhase1 |
|                    ...                     |
|============================================|

XREF
|==================|
| PERSON | PROJECT |
|==================|
| 1      | 1       |
| 2      | 1       |
| 2      | 2       |
|==================|
			

The representation of this data as java classes might look something like:

package com.solarmetric.examples;

...

public class Person
{
    private String      name;
    private String      social;
    private Person      manager;
    private Collection  managedPeople;
    private Collection  projects;
    
    ...
}


public class Project
{
    private String  codeName;
    private Date    start;
    private Date    end;
    private List    people;

    ...
}
			

Given the above classes and tables, the metadata to map them together could be defined as follows:

<?xml version="1.0"?>
<jdo>
    <package name="com.solarmetric.examples">
        <class name="Person">
            <extension vendor-name="kodo" key="table" value="PERSON"/>
            <extension vendor-name="kodo" key="pk-column" value="PK"/>
            <extension vendor-name="kodo" key="lock-column" value="none"/>
            <extension vendor-name="kodo" key="class-column" value="none"/>
            <field name="name">
                <extension vendor-name="kodo" key="data-column" value="NAME"/>
            </field>
            <field name="social">
                <extension vendor-name="kodo" key="data-column" value="SSNUM"/>
            </field>
            <field name="manager">
                <extension vendor-name="kodo" key="data-column" value="MGR"/>
            </field>

            <!-- 
                one-to-many mappings never take schema extensions; all the 
				needed information is available from the related class and its 
                inverse field
            -->
            <field name="managedPeople">
                <collection element-type="Person"/>
                <extension vendor-name="kodo" key="inverse" value="manager"/>
            </field>
            <field name="projects">
                <collection element-type="Project"/>
                <extension vendor-name="kodo" key="inverse" value="people"/>
                <extension vendor-name="kodo" key="table" value="XREF"/>
                <extension vendor-name="kodo" key="data-column" value="PROJECT"/>
                <extension vendor-name="kodo" key="ref-column" value="PERSON"/>
            </field>

        </class>
        <class name="Project">
            <extension vendor-name="kodo" key="table" value="PROJECT"/>
            <extension vendor-name="kodo" key="pk-column" value="PK"/>
            <extension vendor-name="kodo" key="lock-column" value="none"/>
            <extension vendor-name="kodo" key="class-column" value="none"/>
            <field name="codeName">
                <extension vendor-name="kodo" key="data-column" value="CODE_NAME"/>
            </field>
            <field name="start">
                <extension vendor-name="kodo" key="data-column" value="START_DATE"/>
            </field>
            <field name="end">
                <extension vendor-name="kodo" key="data-column" value="END_DATE"/>
            </field>
            <field name="people">
                <collection element-type="Person"/>
                <extension vendor-name="kodo" key="inverse" value="projects"/>
                <extension vendor-name="kodo" key="table" value="XREF"/>
                <extension vendor-name="kodo" key="data-column" value="PERSON"/>
                <extension vendor-name="kodo" key="ref-column" value="PROJECT"/>
            </field>
        </class>
    </package>
</jdo>
    		

Example 4.2. Extensions Under Application Identity

Now we will modify the example a bit for application identity. The new schema is:

PERSON
|===================================================|
|  NAME (PK) | SSNUM (PK)  | MGR_NAME | MGR_SSNUM   |
|===================================================|
|  john      | 123-45-6789 | alice    | 111-22-3333 |
|  fred      | 987-65-4321 | alice    | 111-22-3333 |
|  alice     | 111-22-3333 | NULL     | NULL        |
|                 ...                 |             |
|===================================================|

PROJECT
|==========================================|
| START_DATE  | END_DATE  | CODE_NAME (PK) |
|==========================================|
| 10 25 2000  | NULL      | 2.0a1          |
| 01 10 2001  | 01 31 2001| TestPhase1     |
|                    ...                   |
|==========================================|

XREF
|==========================================|
| PERSON_NAME | PERSON_SSNUM  | PROJECT    |
|==========================================|
| john        | 123-45-6789   | 2.0a1      |
| fred        | 987-65-4321   | 2.0a1      |
| alice       | 111-22-3333   | TestPhase1 |
|==========================================|
			

The classes remain unchanged. Application identity classes would have to be introduced for Person and Project, but those will not be shown here. To review, the classes representing the above tables are:

package com.solarmetric.examples;

...

public class Person
{
    private String      name;
    private String      social;
    private Person      manager;
    private Collection  managedPeople;
    private Collection  projects;
    
    ...
}


public class Project
{
    private String  codeName;
    private Date    start;
    private Date    end;
    private List    people;

    ...
}
			

Given the above classes and tables, the metadata to map them together could now be defined as follows:

<?xml version="1.0"?>
<jdo>
    <package name="com.solarmetric.examples">
        <class name="Person" objectid-class="...">
            <extension vendor-name="kodo" key="table" value="PERSON"/>
            <extension vendor-name="kodo" key="lock-column" value="none"/>
            <extension vendor-name="kodo" key="class-column" value="none"/>
            <field name="name" primary-key="true">
                <extension vendor-name="kodo" key="data-column" value="NAME"/>
            </field>
            <field name="social" primary-key="true">
                <extension vendor-name="kodo" key="data-column" value="SSNUM"/>
            </field>
            <field name="manager">
                <extension vendor-name="kodo" key="name-data-column" value="MGR_NAME"/>
                <extension vendor-name="kodo" key="social-data-column" value="MGR_SSNUM"/>
            </field>

            <!-- 
                one-to-many mappings never take schema extensions; all the 
				needed information is available from the related class and its 
                inverse field
            -->
            <field name="managedPeople">
                <collection element-type="Person"/>
                <extension vendor-name="kodo" key="inverse" value="manager"/>
            </field>
            <field name="projects">
                <collection element-type="Project"/>
                <extension vendor-name="kodo" key="inverse" value="people"/>
                <extension vendor-name="kodo" key="table" value="XREF"/>
                <extension vendor-name="kodo" key="codeName-data-column" value="PROJECT"/>
                <extension vendor-name="kodo" key="name-ref-column" value="PERSON_NAME"/>
                <extension vendor-name="kodo" key="social-ref-column" value="PERSON_SSNUM"/>
            </field>

        </class>
        <class name="Project" objectid-class="...">
            <extension vendor-name="kodo" key="table" value="PROJECT"/>
            <extension vendor-name="kodo" key="lock-column" value="none"/>
            <extension vendor-name="kodo" key="class-column" value="none"/>
            <field name="codeName" primary-key="true">
                <extension vendor-name="kodo" key="data-column" value="CODE_NAME"/>
            </field>
            <field name="start">
                <extension vendor-name="kodo" key="data-column" value="START_DATE"/>
            </field>
            <field name="end">
                <extension vendor-name="kodo" key="data-column" value="END_DATE"/>
            </field>
            <field name="people">
                <collection element-type="Person"/>
                <extension vendor-name="kodo" key="inverse" value="projects"/>
                <extension vendor-name="kodo" key="table" value="XREF"/>
                <extension vendor-name="kodo" key="name-data-column" value="PERSON_NAME"/>
                <extension vendor-name="kodo" key="social-data-column" value="PERSON_SSNUM"/>
                <extension vendor-name="kodo" key="codeName-ref-column" value="PROJECT"/>
            </field>
        </class>
    </package>
</jdo>