我希望使用Java的ORM框架将领域模型映射到关系数据库。不幸的是,这些框架似乎都没有为实现多个接口的类提供足够的支持。例如,我想要映射以下类型:
所以我想实现的是,报价可以引用任何可引用物(股票、股票指数和其他),而交易只能引用可交易实体。我已经尝试使用OpenJPA和(纯)Hibernate,但都没有成功,尽管后者对接口的支持看起来很有前途。
有没有框架可以处理我的情况?或者有没有很好的理由不将其映射到数据库中?如果有,应该如何修改我的模型?
我的初始Hibernate映射大致如下(我没有显示任何OpenJPA的内容,因为它不支持接口继承,或者至少我无法弄清楚):
这与Hibernate文档中的示例几乎完全相同,将产生一个带有id和字符串判别器列的表quotable、一个带有id和指数名称的表stock_index以及一个带有id和股票名称的表stock。到目前为止还不错...但是,我该怎么处理Tradeable接口?我必须设置一个单独的层次结构,并在两个层次结构中映射Stock。我确实尝试过这样做,但必须为Stock定义不同的实体名称(并需要包含此修补程序),但由于外键冲突,这也行不通。我尝试了一些其他不起眼的事情,但也没有成功。总之,两次映射股票不是一个好的解决方案,因为应用程序必须记住为每个接口添加两次股票实例。我宁愿让框架自动处理这个问题。
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的内容,因为它不支持接口继承,或者至少我无法弄清楚):
<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和字符串判别器列的表quotable、一个带有id和指数名称的表stock_index以及一个带有id和股票名称的表stock。到目前为止还不错...但是,我该怎么处理Tradeable接口?我必须设置一个单独的层次结构,并在两个层次结构中映射Stock。我确实尝试过这样做,但必须为Stock定义不同的实体名称(并需要包含此修补程序),但由于外键冲突,这也行不通。我尝试了一些其他不起眼的事情,但也没有成功。总之,两次映射股票不是一个好的解决方案,因为应用程序必须记住为每个接口添加两次股票实例。我宁愿让框架自动处理这个问题。
理想情况下,Hibernate会允许扩展多个接口,例如:(请注意“subclass”元素上的“extends”属性):
<subclass name="Stock" extends="Quotable, Tradable" >
<join table="stock" >
<key column="id"/>
<property name="name" column="name" access="field" />
</join>
</subclass>
是否还有其他映射示例的想法?我现在了解到了<any>
元素,它看起来可能适合我,但我仍需理解其所有含义。
其他框架呢?我听说EclipseLink也支持接口,但文档不够完善。