9. 继承映射(Inheritance Mappings) / 9.1. 三种策略 / 9.1.6. Table per concrete class, using implicit polymorphism

另一种可供选择的方法是采用隐式多态:

<class name="CreditCardPayment" table="CREDIT_PAYMENT">
    <id name="id" type="long" column="CREDIT_PAYMENT_ID">
        <generator class="native"/>
    </id>
    <property name="amount" column="CREDIT_AMOUNT"/>
    ...
</class>

<class name="CashPayment" table="CASH_PAYMENT">
    <id name="id" type="long" column="CASH_PAYMENT_ID">
        <generator class="native"/>
    </id>
    <property name="amount" column="CASH_AMOUNT"/>
    ...
</class>

<class name="ChequePayment" table="CHEQUE_PAYMENT">
    <id name="id" type="long" column="CHEQUE_PAYMENT_ID">
        <generator class="native"/>
    </id>
    <property name="amount" column="CHEQUE_AMOUNT"/>
    ...
</class>

注意,我们没有在任何地方明确的提及接口Payment。同时注意 Payment的属性在每个子类中都进行了映射。如果你想避免重复, 可以考虑使用XML实体(例如:位于DOCTYPE声明内的 [ <!ENTITY allproperties SYSTEM "allproperties.xml"> ] 和映射中的&allproperties;)。

这种方法的缺陷在于,在Hibernate执行多态查询时(polymorphic queries)无法生成带 UNION的SQL语句。

对于这种映射策略而言,通常用<any>来实现到 Payment的多态关联映射。

<any name="payment" meta-type="string" id-type="long">
    <meta-value value="CREDIT" class="CreditCardPayment"/>
    <meta-value value="CASH" class="CashPayment"/>
    <meta-value value="CHEQUE" class="ChequePayment"/>
    <column name="PAYMENT_CLASS"/>
    <column name="PAYMENT_ID"/>
</any>