Java ORM:多重(接口)继承

Java ORM:多重(接口)继承,java,orm,interface,multiple-inheritance,Java,Orm,Interface,Multiple Inheritance,我想使用Java的一个ORM框架将域模型映射到关系数据库。不幸的是,它们似乎都没有足够的支持实现多个接口的类。假设我想映射如下内容: public interface Quotable { } public interface Tradable { } // StockIndex only implements Quotable as it cannot be trade directly public class StockIndex implements Quotable { } //

我想使用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映射看起来是这样的(我没有展示任何OpenJPA的东西,因为它不支持接口继承,或者至少我不知道如何实现):


这与中的示例几乎相同,并导致一个带有id和字符串鉴别器列的表可引用,一个带有id和索引名称的表股票索引,以及一个带有id和股票名称的表股票。到目前为止还不错

但是我该如何处理可交易接口呢?我必须设置一个单独的层次结构,并在两个层次结构中映射库存。我确实尝试过这样做,但必须为股票定义不同的实体名称(并且需要包含),但由于外键冲突,这也不起作用。我尝试了其他一些不起眼的东西,但也没用

无论如何,映射股票两次并不是一个好的解决方案,因为应用程序必须记住添加股票实例两次——每个接口一次。我宁愿让框架自动处理这个问题

理想情况下,Hibernate允许扩展多个接口,例如(注意subclass元素上的extends属性):


还有其他想法如何映射我的示例吗?我现在已经了解了这个元素,它看起来可能对我有用,但我还没有理解它的所有含义


其他框架呢?我听说EclipseLink也对接口提供了一些支持,但没有很好的文档记录。

我认为您不会发现任何ORM能够很好地处理接口层次结构。 所以我在这里不讨论ORMs,但我将向您展示如何使用Qi4j实现您的示例

Qi4j是一种面向组合编程的实现,使用标准Java平台和一个以领域为中心的应用程序开发框架,包括AOP、DI和DDD的演变概念。看

在Qi4j中,域状态使用实体和值进行建模。在下面的代码示例中,我假设一切都是一个实体,但您的里程数可能会有所不同

由于实体仅使用接口声明,所以您的用例应该非常适合

interface Quotable { ... }
interface Tradable { ... }
interface StockIndex extends Quotable { ... }
interface Stock extends Quotable, Tradable { ... }
interface Quote {
    Association<Quotable> quotable();
}
interface Trade {
    Association<Tradable> tradable();
}
接口可引用{…}
接口可交易{…}
接口StockIndex扩展了可引用的{…}
接口股票扩展可报价、可交易{…}
接口报价{
关联可引用();
}
接口贸易{
可交易协会();
}
然后,您可以将这些存储在EntityStore中,并使用查询API轻松地检索它们(并且以完全多态的方式)

请注意,Qi4j EntityStores不仅基于SQL,而且还支持NoSQL数据库。请参见此处的可用扩展:


如果您有更多问题,请参阅Qi4j文档。

您还没有真正解释什么不起作用,或者您是如何进行映射的。现在,我已经包括了我的Hibernate映射,并提供了一些关于我尝试的内容的详细信息。希望它现在变得更加清晰。
<subclass name="Stock" extends="Quotable, Tradable" >
    <join table="stock" >
        <key column="id"/>
        <property name="name" column="name" access="field" />
    </join>
</subclass>
interface Quotable { ... }
interface Tradable { ... }
interface StockIndex extends Quotable { ... }
interface Stock extends Quotable, Tradable { ... }
interface Quote {
    Association<Quotable> quotable();
}
interface Trade {
    Association<Tradable> tradable();
}