2009-06-15 8 views
34

Mam dwie tabele: Ta i Tb. Mają dokładnie taką samą strukturę tabeli, ale różne nazwy tabel.JPA, Jak używać tej samej klasy (obiektu) do odwzorowania różnych tabel?

Próbuję utworzyć jedną klasę obiektu do odwzorowania struktur tabeli. Niektóre z moich popularnych modułów aplikacji będą używać tej klasy encji do dynamicznego sprawdzania i aktualizowania wartości Ta lub Tb na podstawie parametrów. Czy można to zrobić w WZP? Jak mogę napisać program dynamicznie odwzorowujący klasę encji na różne tabele w czasie wykonywania?

Odpowiedz

37

Nie jesteś pewien, że możesz to zrobić dokładnie tak, jak chcesz, ale możesz użyć dziedziczenia, aby uzyskać ten sam wynik.

ABST posiada wszystkie pola, ale nie @Table adnotacji

Ta i Tb dziedziczenia z ABST i mają @Table Adnotacja każdy

Zastosowanie

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 

w ABST.

Przykładowy kod:

@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

To działa, dzięki! Jednak w przypadku Toplink funkcja TABLE_PER_CLASS nie jest obsługiwana. Próbowałem metody @mappedSuperClass i działa również. –

+4

Dla każdego, kto nie ma pewności co do dziedziczenia w porównaniu z MappedSuperClass, są one bardzo dobrze opisane i porównane tutaj: http://stackoverflow.com/a/9669719/2278186 – SatA

7

Można również zrobić to bez użycia podklasy jeśli używasz dwóch różnych jednostek wytrwałości.

Każda jednostka trwałości może określać unikalny zestaw odwzorowań (w tym nazwę tabeli). Jednym ze sposobów osiągnięcia tego jest utworzenie dwóch plików orm.xml. W persistence.xml trzeba coś takiego:

<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> 

Następnie w ciągu 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> 

A w ciągu 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> 

Ty Będziesz musiał utworzyć osobny EntityManagerFactory dla każdej PersistenceUnit (prawdopodobnie nie tego, czego chcesz), ale jeśli chciałbyś użyć tej samej klasy w różnych bazach danych (z różnymi nazwami tabel), byłby to właściwy sposób.

18

Utwórz klasę abstrakcyjną (klasa szablonu) z adnotacją @MappedSuperclass, a następnie ją rozszerz. Każda klasa, która się rozszerza, używa przypisów @table, @entity i zawiera tylko pusty konstruktor. Cały kod będzie w twojej klasie rodzica. Na twoich metodach używasz generics wskazując, że twoja encja parametrów rozciąga się od templateClass i żadne dalsze zmiany kodu nie są potrzebne. Odpowiednie mapowania będą w każdym z synów, których zdasz.

Powiązane problemy