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>