Mi piacerebbe mappare un modello di dominio a un database relazionale utilizzando uno dei framework ORM per Java. Sfortunatamente, nessuno di questi sembra avere un supporto adeguato per le classi che implementano più interfacce. Dire che voglio mappare qualcosa di simile:ORM Java: ereditarietà multipla (interfaccia)
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;
}
Quindi quello che sto cercando di realizzare è che un preventivo può fare riferimento a qualsiasi Quotable (azionario, StockIndex e altri), mentre un commerciale può fare riferimento solo entità negoziabili. Ho provato OpenJPA e (semplice) Hibernate senza fortuna anche se il supporto di quest'ultimo per le interfacce sembrava promettente.
C'è qualche framework in grado di gestire il mio scenario? O ci sono dei buoni motivi per cui questo non dovrebbe essere mappato su un database? Se sì, come dovrebbe essere modificato il mio modello?
mio mapping Hibernate iniziale sembrava qualcosa di simile (non sto mostrando alcun roba OpenJPA in quanto non supporta l'ereditarietà di interfaccia o almeno io non riuscivo a capire come):
<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>
Questo è praticamente identico all'esempio nei Hibernate documentation e risultati in una tabella citabile con un ID e una colonna stringa discriminatore, un tavolo stock_index con un id e l'indice' nome e un tavolo archivio con un id e la nome del titolo. Fin qui tutto bene ...
Ma cosa devo fare con l'interfaccia commerciale? Dovrei impostare una gerarchia separata e mappare azioni in entrambe le gerarchie. Ho provato questo, ma ho dovuto definire diversi nomi di entità per Stock (e necessario includere this patch) ma anche questo non ha funzionato a causa di violazioni di chiave esterna. Ho provato un paio di altre cose oscure che non ha funzionato neanche.
In ogni caso, mappare lo stock due volte non sarebbe una buona soluzione in quanto l'applicazione dovrebbe ricordare di aggiungere istanze di magazzino due volte, una per ogni interfaccia. Preferirei che il framework gestisse questo automatismo.
Idealmente Hibernate permetterebbe di estendere più interfacce, vale a dire qualcosa di simile (si noti l'estende attributo sul sottoclasse elemento):
<subclass name="Stock" extends="Quotable, Tradable" >
<join table="stock" >
<key column="id"/>
<property name="name" column="name" access="field" />
</join>
</subclass>
Tutte le altre idee come il mio esempio può essere mappato? Ora ho imparato a conoscere l'elemento <any>
che sembra funzioni per me, ma devo ancora comprenderne tutte le implicazioni.
E gli altri quadri? Ho sentito che EclipseLink ha anche qualche supporto per le interfacce, ma non è ben documentato.
Non hai davvero spiegato cosa non funziona o come stai facendo la mappatura. –
Ora ho incluso la mia mappatura di Hibernate con ulteriori dettagli su ciò che ho provato. Spero che ora sia più chiaro. – kaiboy