2012-04-01 25 views
6

JavaのORMフレームワークの1つを使用して、ドメインモデルをリレーショナルデータベースにマップしたいと考えています。残念ながら、それらのどれも複数のインタフェースを実装しているクラスを適切にサポートしているようには見えません。それでは、私が達成しようとしていることは展覧会だけで売買可能なエンティティを参照することができながら、引用はどのQuotable(証券、StockIndexなど)を参照することができるということですJava ORM:複数(継承)継承

public interface Quotable { 
} 

public interface Tradable { 
} 

// StockIndex only implements Quotable as it cannot be trade directly 
public class StockIndex implements Quotable { 
} 

// Stock implements both interfaces as there are market quotes and can be traded 
public class Stock implements Quotable, Tradable { 
} 

public class Quote { 
    private Quotable quotable; 
} 

public class Trade { 
    private Tradable tradable; 
} 

:私のようなものをマッピングしてみたいと思います。私は、OpenJPAと(プレーン)Hibernateを幸運に向かわせて試しましたが、後者のインターフェースのサポートは有望でした。

私のシナリオを処理できるフレームワークはありますか?または、これをデータベースにマップしない理由がありますか?もしそうなら、私のモデルはどのように修正すべきですか?

<hibernate-mapping package="com.foo"> 
    <class name="Quotable" table="quotable" > 
     <id type="java.lang.Long" column="id"> 
      <generator class="sequence" /> 
     </id> 

     <discriminator column="type" type="string" /> 

     <subclass name="StockIndex"> 
      <join table="stock_index" > 
       <key column="id"/> 
       <property name="name" column="name" access="field" /> 
      </join> 
     </subclass> 

     <subclass name="Stock"> 
      <join table="stock" > 
       <key column="id"/> 
       <property name="name" column="name" access="field" /> 
      </join> 
     </subclass> 
    </class> 
</hibernate-mapping> 

これは、次のとおりです。

私の最初のHibernateのマッピングは、この(それはインターフェースの継承または少なくともをサポートしていないとして、私は任意のOpenJPAのものを示していないよ、私は方法を見つけ出すことができませんでした)のようなものが見えましたテーブルのIDと文字列の識別カラム、テーブルIDとをIDとインデックス」名とテーブル株式stock_indexquotableHibernate documentationと結果の例とほとんど同じ株式の名前。これまでのところとても良い...

しかし、私はTradeableインターフェイスで何をしますか?私は別の階層をセットアップし、両方の階層にストックをマップする必要があります。私はこれを試してみましたが、株式の異なるエンティティ名を定義しなければなりませんでした(そしてthis patchを含む必要がありました)が、これは外部キー違反のためにも機能しませんでした。私はどちらかといえばうまくいきませんでした。

とにかく、ストックを2回マッピングすることは良い解決策ではありません。これは、アプリケーションがストック・インスタンスを2回追加することを覚えておく必要があるからです。私はむしろこのフレームワークをこのautomaticalyに処理させるでしょう。

理想的には、Hibernateは、複数のインターフェイスを拡張することが可能になる

、すなわちのようなもの(が延び属性をサブクラス要素に注意してください):

<subclass name="Stock" extends="Quotable, Tradable" > 
    <join table="stock" > 
     <key column="id"/> 
     <property name="name" column="name" access="field" /> 
    </join> 
</subclass> 

私の例をマッピングすることができますどのように他のアイデア?私は今それが私のために働くかもしれないように見える<any>要素について学んだが、私はまだすべての意味を理解していない。

他のフレームワークについてはどうですか?私は、EclipseLinkもインターフェースをサポートしていると聞いてきましたが、それは十分に文書化されていません。

+5

あなたは実際に何がうまくいかないか、またはマッピングをどうやってやっているのかを本当に説明していません。 –

+0

私はHibernateマッピングを含めましたが、試したことの詳細がいくつかあります。今すぐもっと明確になることを願っています。 – kaiboy

答えて

3

私は、あなたがORMがインターフェイス階層をうまく処理できるとは思わないと思います。 ここではORMについては言及しませんが、Qi4jを使用してサンプルを実装する方法を説明します。

Qi4jは、AOP、DI、DDDの進化した概念を含む、ドメイン中心のアプリケーション開発のための標準Javaプラットフォームとフレームワークを使用した複合指向プログラミングの実装です。 http://qi4j.org

Qi4jでは、ドメイン状態がエンティティと値を使用してモデル化されています。次のコードサンプルでは、​​すべてがエンティティであると仮定していますが、あなたの走行距離は異なる場合があります。

エンティティはインターフェイスのみを使用して宣言されるため、ユースケースはうまく収まるはずです。

interface Quotable { ... } 
interface Tradable { ... } 
interface StockIndex extends Quotable { ... } 
interface Stock extends Quotable, Tradable { ... } 
interface Quote { 
    Association<Quotable> quotable(); 
} 
interface Trade { 
    Association<Tradable> tradable(); 
} 

あなたはその後、EntityStoreで論文を保存し、簡単にそれらを取得するためのクエリAPIを使用して(と完全にポリモーフィックな方法で)することができます。

Qi4j EntityStoresはSQLベースだけでなく、NoSQLデータベースもサポートしています。利用可能な拡張子はこちらをご覧ください:http://qi4j.org/latest/extensions.html

その他の質問がある場合は、Qi4jのマニュアルを参照してください。