Me gustaría asignar un modelo de dominio a una base de datos relacional utilizando uno de los marcos ORM para Java. Desafortunadamente, ninguno de ellos parece tener soporte adecuado para las clases que implementan múltiples interfaces. Digamos que quiero para mapear algo como:Java ORM: Herencia múltiple (interfaz)
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;
}
Así que lo que estoy tratando de lograr es que una cita se puede hacer referencia a cualquier Quotable (Stock, StockIndex y otros), mientras que un comercio sólo puede hacer referencia a las entidades negociables. Intenté con OpenJPA y Hibernate (sencillo) sin suerte, aunque el soporte de las últimas para las interfaces parecía prometedor.
¿Hay algún marco que pueda manejar mi situación? ¿O hay alguna buena razón por la cual esto no se debe asignar a una base de datos? De ser así, ¿cómo debería modificarse mi modelo?
Mi mapeo inicial de hibernación parecía algo como esto (no estoy mostrando ninguna materia OpenJPA ya que no soporta la herencia de interfaces o al menos yo no pude averiguar cómo):
<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>
Este es prácticamente idéntico al ejemplo de las Hibernate documentation y resultados en una tabla citable con un ID y una columna de cadena discriminador, una mesa stock_index con un ID y el nombre de índice' y una acción tabla con un ID y la el nombre de la acción Hasta ahora todo bien ...
Pero, ¿qué debo hacer con la interfaz Tradeable? Tendría que configurar una jerarquía separada y asignar Stock en ambas jerarquías. Intenté esto, pero tuve que definir diferentes nombres de entidad para Stock (y necesité incluir this patch) pero esto tampoco funcionó debido a violaciones de clave foránea. Probé un par de otras cosas oscuras que tampoco funcionaron.
De todos modos, mapear Stock dos veces no sería una buena solución ya que la aplicación tendría que recordar agregar instancias Stock dos veces, una para cada interfaz. Prefiero que el framework maneje esto automáticamente.
Idealmente Hibernate permitiría extender múltiples interfaces, es decir, algo así como (nótese el extiende atributo en el elementosubclase):
<subclass name="Stock" extends="Quotable, Tradable" >
<join table="stock" >
<key column="id"/>
<property name="name" column="name" access="field" />
</join>
</subclass>
Cualquier otra idea de cómo mi ejemplo se pueden asignar? Ahora he aprendido sobre el elemento <any>
que parece que podría funcionar para mí, pero aún no he entendido todas sus implicaciones.
¿Qué hay de otros marcos? Escuché que EclipseLink también tiene algo de soporte para las interfaces, pero no está bien documentado.
No ha explicado realmente lo que no funciona o cómo está haciendo la asignación. –
Ahora he incluido mi mapeo de Hibernate con más detalles sobre lo que probé. Espero que se vuelva más claro ahora. – kaiboy