簡體   English   中英

Java ORM:多個(接口)繼承

[英]Java ORM: Multiple (interface) inheritance

我想使用一個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;
}

所以我想要實現的是Quote可以引用任何Quotable(股票,StockIndex和其他),而Trade只能引用Tradable實體。 我已經嘗試過OpenJPA和(普通)Hibernate沒有運氣,盡管后者對界面的支持看起來很有希望。

有沒有可以處理我的場景的框架? 或者有什么理由不應該映射到數據庫嗎? 如果是這樣,我的模型應該如何修改?

我最初的Hibernate映射看起來像這樣(我沒有顯示任何OpenJPA的東西,因為它不支持接口繼承或至少我無法弄清楚如何):

<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文檔和結果在新書用一個ID和一個字符串鑒別列,一個ID和索引的名字和一張桌子股票與ID和股票的名稱的表stock_index的表。 到現在為止還挺好...

但是我應該如何處理Tradeable界面? 我必須在兩個層次結構中設置單獨的層次結構並映射Stock。 我確實試過這個但是必須為Stock定義不同的實體名稱(並且需要包含這個補丁 ),但由於外鍵違規,這也沒有用。 我嘗試了其他一些不起作用的模糊不清的東西。

無論如何,兩次映射股票不是一個好的解決方案,因為應用程序必須記住兩次添加Stock實例 - 每個接口一次。 我寧願讓框架自動處理。

理想情況下,Hibernate允許擴展多個接口,例如(注意子類元素上的extends屬性):

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

我的例子如何映射的任何其他想法? 我現在已經了解了<any>元素,看起來它可能對我有用,但我還沒有理解它的所有含義。

其他框架怎么樣? 我聽說EclipseLink也對接口有一些支持,但它沒有很好的文檔記錄。

我認為你不會發現任何能夠很好地處理接口層次結構的ORM。 所以我不會在這里討論ORM,但我將向您展示如何使用Qi4j實現您的示例。

Qi4j是面向復合的編程實現,使用標准Java平台和面向域中心的應用程序開發框架,包括來自AOP,DI和DDD的演化概念。 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文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM