2009-06-15 15 views
34

Ho due tabelle: Ta e Tb. Hanno esattamente la stessa struttura di tabella ma nomi di tabelle differenti.JPA, Come utilizzare la stessa classe (entità) per mappare tabelle diverse?

Provo a creare una classe di entità per mappare le strutture di tabella. Alcuni dei miei moduli applicativi comuni utilizzeranno questa classe di entità per eseguire query e aggiornamenti dinamici su Ta o Tb in base ai parametri. Può essere fatto in JPA? Come posso scrivere il programma per mappare dinamicamente la classe entità su tabelle diverse in fase di esecuzione?

risposta

37

Non siete sicuri di poterlo fare esattamente come volete ma potete usare l'ereditarietà per produrre lo stesso risultato.

ABST ha tutti i campi, ma nessuna annotazione @Table

Ta e Tb ereditare da ABST e hanno un'annotazione @Table ogni

Usa

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 

in Abst.

codice di esempio:

@Entity 
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 
public class abstract AbsT { 
    @Id Long id; 
... 
} 

@Entity 
@Table(name = "Ta") 
public class Ta extends AbsT { 
... 
} 

@Entity 
@Table(name = "Tb") 
public class Tb extends AbsT { 
... 
} 
+6

Funziona, grazie! Tuttavia, per Toplink, TABLE_PER_CLASS non è supportato. Ho provato il metodo @mappedSuperClass e funziona pure. –

+4

Per chi non è sicuro di Ereditarietà rispetto a MappedSuperClass, vengono descritti e confrontati molto bene qui: http://stackoverflow.com/a/9669719/2278186 – SatA

7

Si può anche fare questo senza usare le sottoclassi se si utilizzano due diverse unità di persistenza.

Ciascuna unità di persistenza può specificare un insieme univoco di mapping (incluso il nome della tabella). Un modo per ottenere ciò è creare due file orm.xml. In persistence.xml avrete bisogno di qualcosa di simile:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    version="1.0"> 

    <persistence-unit name="mapping-1"> 
     . . . 
     <mapping-file>orm-1.xml</mapping-file> 
     . . . 
    </persistence-unit> 

    <persistence-unit name="mapping-2"> 
     . . . 
     <mapping-file>orm-2.xml</mapping-file> 
     . . . 
    </persistence-unit> 
</persistence> 

Poi entro orm-1.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" 
    version="1.0"> 
    <package>mypackage</package> 
    <entity name="myEntity" class="myClass"> 
     <table name="TABLE1"> 
      </table> 
    </entity> 
</entity-mappings> 

E all'interno orm-2.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd" 
    version="1.0"> 
    <package>mypackage</package> 
    <entity name="myEntity" class="myClass"> 
     <table name="TABLE2"> 
      </table> 
    </entity> 
</entity-mappings> 

È Sarà necessario creare una EntityManagerFactory separata per ogni PersistenceUnit (probabilmente non ciò che si desidera), ma se si volesse utilizzare la stessa classe su diversi database (con nomi di tabelle differenti), questa sarebbe una strada da percorrere.

18

Creare una classe astratta (una classe template) con annotazione @MappedSuperclass quindi estenderla. Ogni classe che estende utilizza le annotazioni @table, @entity e non contiene nient'altro che un costruttore vuoto. Tutto il codice sarà nella tua classe genitore. Sui metodi usate generics che indicano che l'entità parametro si estende da templateClass e non sono necessarie ulteriori modifiche al codice. Le mappature corrette saranno in ogni figlio che passi.

Problemi correlati