Speedo Inheritance support manual

 FinalLogo.jpg
 FinalLogo.jpg
  1. General conditions
  2. The support of the filtered mapping
  3. The support of the horizontal mapping
  4. The Animal example
  5. The Article example
  6. The Form example (filter out of the identifier)

Back to the Speedo user manual
Back to the Speedo documentation




General conditions

The main condition of the inheritance support is about the namming of the persistent classes. Indeed according to the JDO specification the identifier has to be the same for all classes in an inheritance tree. Speedo supports application identifier but with a condition: the user must specify a filter permitting to know which persistent class is represented by an identifier instance. Let us take an example in order to explain better this condition.


The support of the filtered mapping

With an filtered mapping of the inheritance, there is one table for all classes of the inheritance tree. You define the mapping of fields with the field declaration. By this way there is no duplicate declaration of the mapping (column name, table name, ...). You only have to specify the 'inheritance-mapping' extension in the subclasses, with the value 'filtered'.


The support of the horizontal mapping

With an horizontal mapping of the inheritance, there is one table for each persistent and concret class of the inheritance tree. In each persistent class, you define the mapping of the class and its fields. There is a particular way to define the mapping of the inherited fields.

The horizontal mapping of the inheritance will be supported soon.


The animal example

You have an abstract Animal class with two sub classes: Kangaroo and Koala. The Zoo class has a multi valued reference to Animal instance. Of course, the collection can contain Kangaroo and Koala instance.


The common identifier is composed by field animal fields. In our case, the identifier is composed by the couple (name, species). The species field permits to know the instance type (Animal, Kangaroo or Koala). Here is an example of the java declaration of the persistent classes.

abstract class Animal {
private boolean sex;
private String name;
private String species;
private Zoo zoo;
public Animal(String name, String species) {
this.name = name;
this.species = species;
}
public String getName() { return name; }
public String getSpecies() { return species; }
public boolean getSex() { return sex; }
public void setSex(boolean sex) { this.sex = sex; }
}
class Kangaroo extends Animal {
private int jumpLength;
public Kangaroo(String name) {
super(name, "kangaroo");
}
public int getJumpLength() { return jumpLength; }
public void setJumpLength(boolean jumpLength) { this.jumpLength = jumpLength; }
}
class Koala extends Animal {
private int lifeTime;
public Koala(String name) {
super(name, "koala");
}
public int getLifeTime() { return lifeTime; }
public void setLifeTime(boolean lifeTime) { this.lifeTime = lifeTime; }
}
class Zoo {
private String name;
private Collection animals
public Zoo(String name) {
this.name = name;
animals = new ArrayList();
}
public String getName() { return name; }
public Collection getAnimals() { return animals; }
}

You can see that the species field is constant when the class is a Kangaroo or a Koala. The species field has to be used to distinguish classes. Here the filter is very simple, it is the field species. In .jdo file you have

The animal example with a filtered mapping

The filtered mapping applied to the animal example is represented by the following diagrams:


The TAnimal table contains the instances of the Kangaroo and Koala classes. The following .jdo sections describe how to defined the filtered mapping:

<class name="Animal" identity-type="application" objectid-class="AnimalId"/>
<extension vendor-name="speedo" key="sql-name" value="TANIMAL"/>
<extension vendor-name="speedo" key="inheritance-filter" value="species"/>

<field name="name" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="NAME"/>
</field>
<field name="species" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="SPECIE"/>
</field>
...
</class>

<class name="Kangaroo" persistence-capable-superclass="Animal"/>
<extension vendor-name="speedo" key="inheritance-key" value="kangaroo"/>
<extension vendor-name="speedo" key="inheritance-mapping" value="filtered"/>

<field name="jumpLength">
<extension vendor-name="speedo" key="sql-name" value="JUMP"/>
</field>
...
</class>

<class name="Koala" persistence-capable-superclass="Animal"/>
<extension vendor-name="speedo" key="inheritance-key" value="koala"/>
<extension vendor-name="speedo" key="inheritance-mapping" value="filtered"/>

<field name="lifeTime">
<extension vendor-name="speedo" key="sql-name" value="LIFE"/>
</field>
...
</class>

You can note that the table name is defined in the root class even if the class is abstract. The mapping of the Animal fields are also defined in the section corresponding to the animal class. In the other hand the field mapping of Kangaroo or Koala classes are defined in their own class.


The animal example with an horizontal mapping

soon supported


The article example

You have an abstract Article class with two sub classes: Service and Materiel. The Catalogue class has a multi valued reference to Article instances. Of course, the collection contains Service and Materiel instances only.


The common identifier is a long field of the Article class. An example of the java declaration of the persistent classes.

abstract class Article {
private long id;
private String name;
private Catalog catalog;
public Article(long id) {
this.id = id;
}
public String getId() { return id; }
}
class Service extends Article {
private String f1;
public Service(long value) {
super(2 * value);
}
}
class Materiel extends Article {
private String f2;
public Materiel(long value) {
super(2 * value + 1);
}
}
class Catalog {
private String name;
private Collection articles
public Catalog(String name) {
this.name = name;
articles = new ArrayList();
}
}

You can see that the id value is pair for Service instances whereas it was impair for Materiel instances. Here the filter is an arithmetic expression: (id % 2). In .jdo file you have

The article example with a filtered mapping

The filtered mapping applied to the Article example is represented by the following diagrams:

Catalog table image
article table image

The TArcticle table contains the instances of the Service and Materiel classes. The following .jdo sections describe how to define the filtered mapping:

<class name="Article" identity-type="application"/>
<extension vendor-name="speedo" key="sql-name" value="TARTICLE"/>
<extension vendor-name="speedo" key="inheritance-filter" value="(id % 2)"/>

<field name="id" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="LID"/>
</field>
<field name="name">
<extension vendor-name="speedo" key="sql-name" value="NAME"/>
</field>
<field name="catalog">
<extension vendor-name="speedo" key="target-foreign-keys" value="CATALOG"/>
</field>
</class>

<class name="Service" persistence-capable-superclass="Article"/>
<extension vendor-name="speedo" key="inheritance-key" value="0"/>
<extension vendor-name="speedo" key="inheritance-mapping" value="filtered"/>

<field name="f1">
<extension vendor-name="speedo" key="sql-name" value="F1"/>
</field>
</class>

<class name="Materiel" persistence-capable-superclass="Article"/>
<extension vendor-name="speedo" key="inheritance-key" value="1"/>
<extension vendor-name="speedo" key="inheritance-mapping" value="filtered"/>

<field name="f2">
<extension vendor-name="speedo" key="sql-name" value="F2"/>
</field>
</class>

You can note that the table name is defined in the root class even if the class is abstract. The mapping of the Article fields are also defined in the section corresponding to the Article class. On the other hand the field mappings of Service or Materiel classes are defined in their own class.


The article example with an horizontal mapping

soon supported

The form example

This is an example of declaring the filter out of the identifier of the super class.
As you can see below, the abstract Form class has two sub classes: BookForm and PurchaseForm.


The common identifier for the  BookForm and PurchaseForm instances is the id field. The title field is the filter that makes the difference between a BookForm and a PurchaseForm instance. The java declaration of the persistent classes is as follows:

abstract class Form {
//the pk
private int id;
//the filter
private String title;
private ContactDetails contactDetails;

public Form(int id, String title, ContactDetails contactDetails) {
this.id = id;
this.title = title;
this.contactDetails = contactDetails;
}

public ContactDetails getContactDetails() {return contactDetails;}
public void setContactDetails(ContactDetails contactDetails) {this.contactDetails = contactDetails;}
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getTitle() {return title;}
public void setTitle(String title) {this.title = title;}
}

class BookForm extends Form {

private int validTime;

public BookForm(int id, ContactDetails contactDetails, int validTime) {
super(id, "book", contactDetails);
this.validTime = validTime;
}

public int getValidTime() {return validTime;}
public void setValidTime(int validTime) {this.validTime = validTime;}
}

class PurchaseForm extends Form {

private int total;
private CreditCard creditCard;

public PurchaseForm(int id, ContactDetails contactDetails, int total, CreditCard creditCard) {
super(id, "purchase", contactDetails);
this.total = total;
this.creditCard = creditCard;
}

public int getTotal() {return total;}
public void setTotal(int total) {this.total = total;}
public CreditCard getCreditCard() {return creditCard;}
public void setCreditCard(CreditCard creditCard) {this.creditCard = creditCard;}
}

You can see that the title field is constant when the class is a BookForm or a PurchaseForm. The title field is used to distinguish classes. In .jdo file you have

The form example with a filtered mapping

The filtered mapping applied to the form example is represented by the following diagram:


The FILTER_FORM table contains the instances of both BookForm and PurchaseForm classes. The following .jdo section describes how to define the filtered mapping:

<class name="Form" identity-type="application">
<extension vendor-name="speedo" key="sql-name" value="FILTER_FORM"/>
<extension vendor-name="speedo" key="inheritance-filter" value="title"/>
<field name="id" primary-key="true">
<extension vendor-name="speedo" key="sql-name" value="FORM_ID"/>
</field>
<field name="title">
<extension vendor-name="speedo" key="sql-name" value="FORM_TITLE"/>
</field>
...
</class>

<class name="BookForm" persistence-capable-superclass="Form">
<extension vendor-name="speedo" key="inheritance-mapping" value="filtered"/>
<extension vendor-name="speedo" key="inheritance-key" value="book"/>
<field name="validTime">
<extension vendor-name="speedo" key="sql-name" value="BOOK_VALID_TIME"/>
</field>
</class>

<class name="PurchaseForm" persistence-capable-superclass="Form">
<extension vendor-name="speedo" key="inheritance-mapping" value="filtered"/>
<extension vendor-name="speedo" key="inheritance-key" value="purchase"/>
<field name="total">
<extension vendor-name="speedo" key="sql-name" value="PURCHASE_TOTAL"/>
</field>
<field name="creditCard" persistence-modifier="persistent">
<extension vendor-name="speedo" key="target-foreign-keys" value="CARD_ID=PURCHASE_CARD_ID"/>
</field>
</class>

You can note that the table name is defined in the root class even if the class is abstract. The mapping of the shared fields is also defined in the section corresponding to the Form class. The mapping of specific fields for a subclass is defined in the subclass jdo section.