ゆーたんのつぶやき このページをアンテナに追加 RSSフィード

ITの可能性を日々追求する岩上由高の日記

2005-05-17 PoEAAのマッピングパターンとHibernate

[]PoEAAのマッピングパターンHibernate PoEAAのマッピングパターンとHibernateを含むブックマーク


Martin Fowler氏のPoEAA(Pattern of Enterprise Application Architecture)の中で

クラス継承をどうやってリレーショナルデータベースマッピングするかのパターン

紹介されています。パターンは全部で3つで


・Single Table Inheritance

  同一の継承ツリーにあるクラスを全て同一のテーブルにマッピングする


Class Table Inheritance

  サブクラスで追加されたプロパティの部分のみ別テーブルにマッピング

  サブクラスインスタンスを取得する際には複数のテーブルを結合する


・Concrete Table Inheritance

  サブクラス毎に個別のテーブルにマッピングする


ということになっています。

Hibernateもちょうどこれに対応するマッピングの設定を持っていますので

整理のためにちょっとまとめてみました。


・subclass

 これがPoEAAでの「Single Table Inheritance」に相当します。

 

  <hibernate-mapping>
   <class name="Employee" descriminator="EMP" table="EMPLOYEE">
       <id name="id" column="ID" type="string">
         <generator class="assigned"/>
       </id>
       <version name="version" column="VERSION" type="integer" unsaved-value="null"/>
       <property name="name" column="NAME" type="string"/>
       <property name="salary" column="SALARY" type="integer"/>
       <descriminator column="CLASS" type="string"/>
    </class>
    <subclass name="Executive" descriminator="EXE">
        <property name="post" column="POST" type="string"/>
      </subclass>
   </hibernate-mapping>
 

この場合の特徴は同じテーブル内でクラスの種別を識別するために

 識別子(descriminator)が必要になる点です。各クラスの定義で

 descriminatorが指定されています。


・joined-subclass

 PoEAAでの「Class Table Inheritance」に相当するものです。

 

  <hibernate-mapping>
   <class name="Employee" table="EMPLOYEE">
       <id name="id" column="ID" type="string">
         <generator class="assigned"/>
       </id>
       <version name="version" column="VERSION" type="integer" unsaved-value="null"/>
       <property name="name" column="NAME" type="string"/>
       <property name="salary" column="SALARY" type="integer"/>
     </class>
    <joined-subclass name="Executive" table="EXECUTIVE">
        <key column="ID"/>
        <property name="post" column="POST" type="string"/>
      </joined-subclass>
   </hibernate-mapping>
 

 このケースではdescriminatorがなくなった代わりにサブクラスに<key>の

 定義が入っています。このkeyラムによって結合対象となる親クラスのレ

 コードを特定します。subclass側にもtable属性がありますので、サブクラス

 で追加された属性については親クラスとは別のテーブルに格納されることが

 わかります。

・union-subclass

 

  <hibernate-mapping>
   <class name="Employee" table="EMPLOYEE">
       <id name="id" column="ID" type="string">
         <generator class="assigned"/>
       </id>
       <version name="version" column="VERSION" type="integer" unsaved-value="null"/>
       <property name="name" column="NAME" type="string"/>
       <property name="salary" column="SALARY" type="integer"/>
     </class>
    <union-subclass name="Executive" table="EXECUTIVE">
       <id name="id" column="ID" type="string">
         <generator class="assigned"/>
       </id>
       <version name="version" column="VERSION" type="integer" unsaved-value="null"/>
       <property name="name" column="NAME" type="string"/>
       <property name="salary" column="SALARY" type="integer"/>
       <property name="post" column="POST" type="string"/>
      </union-subclass>
   </hibernate-mapping>
 

 この場合には全く別のテーブルになるので、親クラス存在しているプロパティ

 サブクラスで定義しています。実質的には個別にマッピングを行なったのとほとん

 ど差はありません。


Hibernate3.xからはサブクラス定義にextends属性を使って親クラスを指定することで

マッピング定義ファイルを親クラスと分けることができるようになりました。上記の例

はいずれも親クラスと同じマッピング定義ファイルサブクラスの定義を記述していま

すが、これらを分けることでサブクラスの追加が容易になります。

トラックバック - http://d.hatena.ne.jp/dufresne/20050517