According to the Hibernate Reference Documentation it should be possible to mix different inheritance mapping strategies when using Hibernate’s XML-Metadata (…)
Actually, it’s not really supported, they are “cheating” using a secondary table to switch from the single table strategy in the example of the documentation. Quoting Java Persistence with Hibernate:
You can map whole inheritance
hierarchies by nesting
<union-subclass>
,<sub- class>
,
and<joined-subclass>
mapping
elements. You can’t mix them — for
example, to switch from a
table-per-class hierarchy with a
discriminator to a normalized
table-per-subclass strategy. Once
you’ve made a decision for an
inheritance strategy, you have to
stick to it.This isn’t completely true, however.
With some Hibernate tricks, you can
switch the mapping strategy for a
particular subclass. For example, you
can map a class hierarchy to a single
table, but for a particular subclass,
switch to a separate table with a
foreign key mapping strategy, just as
with table per subclass. This is
possible with the<join>
mapping
element:<hibernate-mapping> <class name="BillingDetails" table="BILLING_DETAILS"> <id>...</id> <discriminator column="BILLING_DETAILS_TYPE" type="string"/> ... <subclass name="CreditCard" discriminator-value="CC"> <join table="CREDIT_CARD"> <key column="CREDIT_CARD_ID"/> <property name="number" column="CC_NUMBER"/> <property name="expMonth" column="CC_EXP_MONTH"/> <property name="expYear" column="CC_EXP_YEAR"/> ... </join> </subclass> <subclass name="BankAccount" discriminator-value="BA"> <property name=account" column="BA_ACCOUNT"/> ... </subclass> ... </class> </hibernate-mapping>
And you could achieve the same with annotations:
Java Persistence also supports this mixed inheritance mapping strategy with annotations. Map the superclass
BillingDetails
withInheritanceType.SINGLE_TABLE
, as you did before. Now map the subclass you want to break out of the single table to a secondary table.@Entity @DiscriminatorValue("CC") @SecondaryTable( name = "CREDIT_CARD", pkJoinColumns = @PrimaryKeyJoinColumn(name = "CREDIT_CARD_ID") ) public class CreditCard extends BillingDetails { @Column(table = "CREDIT_CARD", name = "CC_NUMBER", nullable = false) private String number; ... }
I didn’t test this but you could maybe try to:
- map A using a SINGLE_TABLE strategy
- map BB, CC, etc using the
@SecondaryTable
annotation.
I’ve not tested this, I don’t know if it will work well for BB1, BB2.
Reference
- Java Persistence with Hibernate
- 5.1.5 Mixing inheritance strategies (p207-p210)