I would like to map a domain model to a relational database using one of the Java ORM frameworks. Unfortunately, none of them seem to have adequate support for classes that implement multiple interfaces. Let's say I want to map something like:
public interface Quotable { } public interface Tradable { }
So what I'm trying to achieve is that the Quote can refer to any Quotable (Stock, StockIndex and others), while Trade can only refer to Tradable objects. I tried OpenJPA and (simple) Hibernate with no luck, although the latest interface support looked promising.
Is there any infrastructure that can handle my script? Or are there good reasons why this should not be mapped to a database? If so, how should my model be changed?
My initial Hibernate mapping looked something like this (I don't show any OpenJPA stuff since it doesn't support interface inheritance, or at least I couldn't figure out how):
<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>
This is pretty much identical to the Hibernate documentation example and results in a table enclosed in a table with an identifier and a column discriminator column, table stock_index with an identifier and index name and a table with an identifier and stock name. So far so good ...
But what should I do with the Tradeable interface? I would need to set up a separate hierarchy and a Stock map in both hierarchies. I tried this, but had to define different entity names for Stock (and it was necessary to include this patch ), but it also did not work due to foreign key violations. I tried a couple of other obscure things that didn't work either.
In any case, matching stocks twice would not be a good solution, because the application would have to remember adding stock instances twice - once for each interface. I would prefer a control mechanism in this automatic way.
Ideally, Hibernate allows you to extend several interfaces, that is, something like (note the extends attribute for the subclass element):
<subclass name="Stock" extends="Quotable, Tradable" > <join table="stock" > <key column="id"/> <property name="name" column="name" access="field" /> </join> </subclass>
Any other ideas how my example could be displayed? Now Iβve found out about <any>
, which looks like it might work for me, but I still have to understand all its consequences.
What about other frameworks? I heard that EclipseLink also has some interface support, but it is poorly documented.