The SQL repository supports a simplified form of inheritance that uses an optional one-to-one relationship between the primary table and an auxiliary table. You can define an item descriptor that inherits properties from another item descriptor in the same repository.
In the following example, a simple clothing store catalog offers coats and shorts. You can model this by creating independent item descriptors to represent coats and shorts and putting each in its own database table. The XML repository definition for this model looks something like:
<!-- The "coat" item type --> <item-descriptor name="coat"> <table name="coat" id-column-names="id" type="primary"> <property name="name"/> <property name="description"/> <property name="color"/> <property name="shippingWeight"/> <property name="size"/> <property name="season"/> </table> </item-descriptor> <!-- The "shorts" item type --> <item-descriptor name="shorts"> <table name="shorts" id-column-names="id" type="primary"> <property name="name"/> <property name="description"/> <property name="color"/> <property name="shippingWeight"/> <property name="size"/> <property name="pleated" data-type="boolean"/> </table> </item-descriptor>
And the database data model has two unrelated tables:
This approach has several drawbacks:
Coats and shorts have a lot of properties in common, which in the above model means duplicated database columns and probably duplicated code.
This model does not allow you to easily perform a query like: find all the items of clothing (shorts and coats) that have “Star Wars” in their description
An object-oriented approach like that used by the SQL repository lets you define a base item descriptor class called clothing
to hold the attributes common to coats and shorts. You can use simple inheritance to make coats
and shorts
subclasses of clothing
. You can then model the data in your clothing catalog as follows:
The corresponding XML repository definition (with changes in bold type) looks like this:
<!-- The "clothing" item type, a base type --> <item-descriptor name="clothing" sub-type-property="type"> <!-- This is the primary table that holds clothing data --> <table name="clothing" type="primary" id-column-names="id"> <property name="type" data-type="enumerated"> <option value="coat"/> <option value="shorts"/> </property> <property name="name"/> <property name="description"/> <property name="color"/> <property name="size"/> <property name="shippingWeight"/> </table> </item-descriptor> <!-- The "coat" item type, now a subclass of "clothing" --> <item-descriptor name="coat" super-type="clothing" sub-type-value="coat"> <table name="coat" type="auxiliary" id-column-names="id"> <property name="season"/> </table> </item-descriptor> <!-- The "shorts" item type, now a subclass of "clothing" --> <item-descriptor name="shorts" super-type="clothing" sub-type-value="shorts"> <table name="shorts" type="auxiliary" id-column-names="id"> <property name="pleated" data-type="boolean"/> </table> </item-descriptor>
The new code implements the following changes:
Creates the parent item descriptor,
clothing
, which holds attributes common to thecoat
andshorts
types.Makes types
coat
andshorts
subclasses of theclothing
type.
The clothing
parent item descriptor has a sub-type-property
attribute. This attribute defines the property of the clothing
type that specifies which sub-types can be instantiated. Each item descriptor that extends the clothing
item descriptor must specify a sub-type-value
attribute, which is the value for this property that triggers use of this particular type. The sub-type-value
must not be null. This is the value of the sub-type-property
, which automatically implies this item type. If there is no sub-type-value
, this item-descriptor is never returned from a getItem
or query on one of its super-type
item descriptors. Such an item descriptor may have one or more item descriptors that have it as its super-type and thus can serve as kind of an abstract item-descriptor.
It should be noted that instances of objects are associated with their superclasses by ID. So, in this example, the ID of a coat always has a matching clothing ID.
As noted above, the sub-type-value
of a sub-type item should never be null. If you have clothing items that are neither coats nor shorts, you should create a sub-type-value
in the clothing
item descriptor with a value of clothing
and add a clothing
option to the sub-type-property definition. For example:
<!-- The "clothing" item type, a base type --> <item-descriptor name="clothing" sub-type-property="type" sub-type-value="clothing"> <!-- This is the primary table that holds clothing data --> <table name="clothing" type="primary" id-column-names="id"> <property name="type" data-type="enumerated"> <option value="clothing"/> <option value="coat"/> <option value="shorts"/> <property/> ...
From the Repository API point of view, each ItemDescriptor maps to a single RepositoryView
. When an SQL repository uses item type inheritance, each parent item type results in a RepositoryViewContainer
that contains its subtype views as children.