Using Hibernate3, have read the reference documentation, am most of the way through Hibernate in Action.
I want to use a mixed inheritance mapping strategy, using a combination of table-per-subclass (i.e. join-subclass) and table-per-hierarchy (i.e. subclass, with a discriminator). The problem is that, as I understand it, while the syntax allows me to switch from subclass to join-subclass, it doesn't let me switch the other direction. In other words, the 'superclass table' can contain rows representing instances of different classes, but each 'subclass table' joined to it contains rows representing only one class.
Consider:
Code:
<class name="Item" table="ITEM" discriminator-value="0">
... id, discriminator, properties, associations ...
<subclass name="Source" discriminator-value="1">
<join table="SOURCE">
...
</join>
</subclass>
<subclass name="Document" discriminator-value="2">
<join table="DOCUMENT">
...
</join>
</subclass>
</class>
Source and Document have very different data content, making a join-subclass approach desirable. But each has multiple subclasses that differ not so much in content as behavior--in other words, poster-child cases for using a table-per hierarchy strategy.
Attempt 1:
Code:
<class name="Item" table="ITEM" discriminator-value="0">
... id, discriminator, properties, associations ...
<subclass name="Source" discriminator-value="1">
<join table="SOURCE">
... key, properties, associations ...
</join>
<subclass name="Foo" discriminator-value="3">
</subclass>
<subclass name="Bar" discriminator-value="4">
</subclass>
</subclass>
...
</class>
This parses ok, and it maps the Source class to both ITEM and SOURCE. But Foo and Bar get mapped only to the ITEM table, not to ITEM and SOURCE as intended.
Attempt 2:
Code:
<class name="Item" table="ITEM" discriminator-value="0">
... id, discriminator, properties, associations ...
<subclass name="Source" discriminator-value="1">
<join table="SOURCE">
... key, properties, associations ...
</join>
</subclass>
<subclass name="Foo" discriminator-value="3">
<join table="SOURCE">
... same key, same properties, same associations ...
</join>
</subclass>
<subclass name="Bar" discriminator-value="4">
<join table="SOURCE">
... same key, same properties, same associations ...
</join>
</subclass>
...
</class>
We might call this a mixed table-per-subclass + implicit polymorphism approach. This actually gives close to the desired behavior, in that Source, Foo, and Bar are all mapped to both the ITEM and SOURCE tables. The main indication that it's not quite right is that in the generated DDL, it puts the same foreign key constraint on SOURCE three times. Plus, it doesn't "feel" right to declare Foo and Bar as direct subclasses of Item when they are really subclasses of Source.
So, is this an abomination? is there a better way to do it? All thoughts appreciated. Thanks.