Horizontal inheritance can only be enabled for the topmost class in a hierarchy. Each immediate subclass is stored in its own table with a "copy" of the fields from the superclass. A horizontally mapped class, i.e. the superclass, does not itself have a table. Therefore, a horizontally mapped class cannot be directly persisted; only subclasses of the class can be stored in the database. For this reason, it is recommended (but not required) that horizontally mapped classes be declared abstract.
While using single or multiple field identity, it is required that the horizontally mapped class is declared abstract.
In case of horizontal mapping, the identity and version information is specified at the next derived class, and if the IdentityField and the VersionField specified are fields that belong to the base class, those fields have to be accessible from the derived classes. Therefore, declaring these fields as "Protected" might be the best way, since if these fields are declared as "Private" the enhanced code will not be able to access these fields. The enhancer will check this and report an error.
Each subclass may map the fields inherited from the superclass differently. Each subclass may have its own settings for identity type, objectid-class, key generator and optimistic locking just like a top level class. Classes further down the hierarchy may be mapped with any combination of flat and vertical inheritance.
To enable horizontal mapping, just change the inheritance strategy to horizontal (in the Forward Mapping wizard) for the base class and change the default values for the rest if needed.
For example our ‘WeinerDog’ and ‘Rottweiler’ classes have been mapped vertically. The corresponding tables for the sample class hierarchy, with horizontal mapping are shown below:
Advantages of horizontal mapping are:
- Persisting and modifying instances of subclasses whose superclass uses horizontal mapping is as fast as flat inheritance mapping, since generally only a single INSERT, DELELTE or UPDATE statement will need to be issued
- Fetching a single instance will not require any joins
- Attributes that are common to multiple persistent classes can just be defined in the superclass; this increases the performance and relational design restrictions of using a vertical mapping are reduced
Disadvantages of horizontal mapping are:
- The base class, in this case, is not really handled like other persistent classes but only its members are inherited into its derived classes
- Each class derived from the horizontally mapped base class starts a new hierarchy. This is especially relevant while using single or multiple identity, as in this case, the identity must be defined in the derived classes and not in the base class. Also each directly derived class must declare its own identity type, because identity types are not sharable across hierarchies.
- Querying the topmost class in the hierarchy is expensive as it will require multiple SELECT statements, one for each concrete subclass, to be executed against the database; Querying subclasses is just as efficient as flat mapping
- References to and collections and maps of the topmost class are not supported
- From a relational design standpoint, horizontal mappings are not normalized, since attributes are repeated across different tables