This model is called "Flat Redundant Inheritance Model" (FRIM or "subclass-table" model as called in the JDO 2.0 specification) can be used if you want to model complex inheritance hierarchies in your object model, while you do not want to have the necessary overhead of having one database table for each class in your object hierarchy (as in the thin inheritance model). You may also want to model abstract base classes, which cannot be instantiated separately, but work as foundation block in the inheritance hierarchy.
Using the FRIM you have the possibility to explicitly define, which database tables you want to use, too. The fields necessary for storing the data from the superclasses will be mapped into your specified tables. This means, that an object model field may be stored into multiple database tables (that is the "redundant" part of FRIM).
The following shows the usage of the Flat Redundant Inheritance Model in an example application.
Your object model consist of the business objects Person and Product . Both objects have shared properties, like e.g. the primary key and a number for later reference. These fields will be modeled as an abstract base class Base .
public abstract class Base
{
private int id;
private String number;
public int getId ()
{
return id;
}
public String getNumber ()
{
return number;
}
public void setId (int value)
{
id = value;
}
public void setNumber (String value)
{
number = value;
}
}
The Person class extends this abstract class:
public class Person extends Base
{
private String firstName;
private String name;
private int age;
public String getFirstName () Please note that in order to actually use this model, you should still specify the inheritance provider, which may lead to more necessary fields.
{
return firstName;
}
public String getName ()
{
return name;
}
public int getAge ()
{
return age;
}
public void setFirstName (String value)
{
firstName = value;
}
public void setName (String value)
{
name = value;
}
public void setAge (int value)
{
age = value;
}
}
The Product class extends the abtsract class too:
public class Product extends Base
{
private String name;
private double price;
public String getName ()
{
return name;
}
public double getPrice ()
{
return price;
}
public void setName (String value)
{
name = value;
}
public void setPrice (double value)
{
price = value;
}
}
The next step is to create the mapping for these classes. Here you have to check the following:
The following shows a possible mapping:
<?xml version="1.0" encoding="UTF-8"?>
<jdo xmlns="http://java.sun.com/xml/ns/jdo/jdo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jdo/jdo http://java.sun.com/xml/ns/jdo/jdo_2_0.xsd">
<package name="test">
<class name="Base">
<field name="id" primary-key="true"/>
<extension key="jdbc" vendor-name="ssibo">
<extension key="table-name" value="TBASE" vendor-name="ssibo"/>
<extension vendor-name="ssibo" key="inheritance">
<extension vendor-name="ssibo" key="field-name" value="FCLASSTYPE" />
<extension vendor-name="ssibo" key="subclass" value="Person" />
<extension vendor-name="ssibo" key="subclass" value="Product" />
</extension>
</extension>
</class>
<class name="Person" persistence-capable-superclass="test.Base">
<extension key="jdbc" vendor-name="ssibo">
<extension key="table-name" value="TPERSON" vendor-name="ssibo"/>
<extension key="inherit-fields" value="true" vendor-name="ssibo"/>
</extension>
</class>
<class name="Product" persistence-capable-superclass="test.Base">
<extension key="jdbc" vendor-name="ssibo">
<extension key="table-name" value="TPRODUCT" vendor-name="ssibo"/>
<extension key="inherit-fields" value="true" vendor-name="ssibo"/>
</extension>
</class>
</package>
</jdo>
Defining the JDO mapping this way, the data is stored in following table structure:
CREATE TABLE TPRODUCT (FID INTEGER NOT NULL PRIMARY KEY, FPRICE FLOAT, FNAME VARCHAR(255), FCLASSTYPE VARCHAR(255), FNUMBER VARCHAR(255) ); CREATE TABLE TPERSON (FID INTEGER NOT NULL PRIMARY KEY, FAGE INTEGER, FNAME VARCHAR(255), FCLASSTYPE VARCHAR(255), FFIRSTNAME VARCHAR(255), FNUMBER VARCHAR(255));As you see, the redundant table for the base class is not longer needed, its database fields are mapped into the tables for the subclasses.
The following limitations are known in this version: