永続クラスの継承
永続クラスを継承して、一つのテーブルに対して2つのマッピングを定義してみた。
ところが、親クラスでfind()をかけると、複数のオブジェクト、つまり親クラスと子クラス双方のインスタンスが返却される。
show_sqlをしてみれば、2回のSQLが発行されれていることもわかる。
つまりドキュメントの「4.2. 継承の実装」*1にある記述だけでは不十分だったわけだ。
クラス定義
public class EntityA{ (略) } public class EntityB extends EntityA{ }
<class name="hoge.EntityA" table="HOGE" > (略) </class> <class name="hoge.EntityB" table="HOGE" > (略) </class>
結局必要だったのは、class要素*2の中の「polymorphism」であった。この説明は以下の通り。
暗黙的(Implicit) ポリモーフィズムとは、 スーパークラスや実装するインターフェイスを指すクエリによって、 そのクラスのインスタンスが返されることを意味します。 そしてそのサブクラスのインスタンスは、そのクラス自体の名前が指定されたときだけ返されます。 明示的(Explicit) ポリモーフィズムとは、 クラス名が明示的に指定されたときにだけ、そのインスタンスが返されることを意味します。 そして
要素の中で や とマッピングされているサブクラスのインスタンスだけが返されます。 ほとんどの用途ではデフォルトの polymorphism="implicit" が適切です。 明示的ポリモーフィズムは、異なった2つのクラスが同じテーブルにマッピングされているときに 役立ちます (これはテーブルのカラムのサブセットを含む「軽量」クラスを可能にします)。
つまりスーパークラスを意味するSQL(この場合from EntityA)を実行した場合、デフォルトの設定では子クラスのSQL(from EntityB)も実行されるということか。
そこで明示的ポリモーフィズムを設定する
<class name="hoge.EntityB" table="HOGE" polymorphism="explicit" <=これ > (略) </class>
うーん、しかし親クラス側に「polymorphism」記述しても動いているなぁ。
ここはちょっと調べておかないといけないのかも。