views:

427

answers:

1

Today I faced an interesting issue. I've been having an inheritance hierarchy with Hibernate JPA, with SINGLE_TABLE strategy. Later, I added a superclass to the hierarchy, which defined TABLE_PER_CLASS strategy. The result was that the whole hierarchy stared behaving as TABLE_PER_CLASS. This, of course, seems fair, if we read the @Inheriatance javadoc:

Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy.

Hibernate docs, however, say that:

It is possible to use different mapping strategies for different branches of the same inheritance hierarchy

And continues on the exemptions from this statement. This is done via XML configuration.

So, finally, my question is - is there a way (a hibernate property, perhaps) to enable the aforementioned xml behaviour via annotations, and using EntityManager.

+1  A: 

Well, if you read the "Inheritance" chapter of Hibernate documentation a little further :-) you'll see that the example given for mixing table-per-hierarchy and table-per-subclass strategies is in reality nothing more than table-per-hierarchy with secondary tables thrown in:

<class name="Payment" table="PAYMENT">
    <id name="id" type="long" column="PAYMENT_ID">
        <generator class="native"/>
    </id>
    <discriminator column="PAYMENT_TYPE" type="string"/>
    <property name="amount" column="AMOUNT"/>
    ...
    <subclass name="CreditCardPayment" discriminator-value="CREDIT">
        <join table="CREDIT_PAYMENT">
            <property name="creditCardType" column="CCTYPE"/>
            ...
        </join>
    </subclass>
    <subclass name="CashPayment" discriminator-value="CASH">
        ...
    </subclass>
</class>

You can do the same using @SecondaryTable annotation:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="PAYMENT_TYPE")
@DiscriminatorValue("PAYMENT")
public class Payment { ... }

@Entity
@DiscriminatorValue("CREDIT")
@SecondaryTable(name="CREDIT_PAYMENT", pkJoinColumns={
    @PrimaryKeyJoinColumn(name="payment_id", referencedColumnName="id")
)
public class CreditCardPayment extends Payment { ... }

@Entity
@DiscriminatorValue("CASH")
public class CashPayment extends Payment { ... }
ChssPly76
Thanks. It isn't very beautiful, though :)I was surprised there is no explicit support for this, since it is not such a 'dark-corner-case'.
Bozho