8.6. より複雑な関連マッピング
より複雑な関連結合は 極めて 稀です。Hibernate は、マッピングドキュメントに埋め込まれたSQL フラグメントを使用することで、さらに複雑な状況を扱うことができます。例えば、
accountNumber 、effectiveEndDate 、 effectiveStartDate カラムを持つ account (口座)情報の履歴を扱うテーブルは、以下のようにマッピングします。
<properties name="currentAccountKey">
<property name="accountNumber" type="string" not-null="true"/>
<property name="currentAccount" type="boolean">
<formula>case when effectiveEndDate is null then 1 else 0 end</formula>
</property>
</properties>
<property name="effectiveEndDate" type="date"/>
<property name="effectiveStateDate" type="date" not-null="true"/>
そして、関連を 現時点の インスタンス (
effectiveEndDate が null であるもの)にマッピングします。以下のようになります:
<many-to-one name="currentAccountInfo"
property-ref="currentAccountKey"
class="AccountInfo">
<column name="accountNumber"/>
<formula>'1'</formula>
</many-to-one>
さらに複雑な例では、
Employee(従業員) と Organization(組織) 間の関連が Employment(雇用) テーブルで保持される場合を想像してください。このテーブルには雇用データの履歴がすべて含まれます。すると従業員の 最も最近の 雇用者を表す関連 (最も最近の startDate を持つもの)は、このようにマッピングできます:
<join>
<key column="employeeId"/>
<subselect>
select employeeId, orgId
from Employments
group by orgId
having startDate = max(startDate)
</subselect>
<many-to-one name="mostRecentEmployer"
class="Organization"
column="orgId"/>
</join>
この機能で創造性、柔軟性の幅が出すことができますが、このような場合、普通は HQL や criteria クエリを使う方がより実践的です。