2009-06-15 39 views
34

Tôi có hai bảng: TaTb. Họ có chính xác cấu trúc bảng giống nhau nhưng tên bảng khác nhau.JPA, Làm thế nào để sử dụng cùng một lớp (thực thể) để ánh xạ các bảng khác nhau?

Tôi cố gắng tạo một lớp thực thể để ánh xạ cấu trúc bảng. Một số mô-đun ứng dụng phổ biến của tôi sẽ sử dụng lớp thực thể này để truy vấn động và cập nhật Ta hoặc Tb dựa trên các thông số. Nó có thể được thực hiện trong JPA? Làm thế nào tôi có thể viết chương trình để tự động ánh xạ lớp thực thể đến các bảng khác nhau trong thời gian chạy?

Trả lời

37

Không chắc chắn bạn có thể thực hiện chính xác như bạn muốn nhưng bạn có thể sử dụng thừa kế để tạo ra kết quả tương tự.

Abst có tất cả các lĩnh vực nhưng không có chú thích @Table

Ta và Tb kế thừa từ Abst và có một chú thích @Table mỗi

Sử dụng

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) 

trong Abst.

Mẫu mã:

@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

Nó hoạt động, Cảm ơn! Tuy nhiên, đối với Toplink, TABLE_PER_CLASS không được hỗ trợ. Tôi đã thử phương thức @mappedSuperClass và nó cũng hoạt động tốt. –

+4

Đối với bất kỳ ai không chắc chắn về Inheritance vs MappedSuperClass, chúng được mô tả và so sánh rất tốt ở đây: http://stackoverflow.com/a/9669719/2278186 – SatA

7

Bạn cũng có thể làm điều này mà không sử dụng lớp con nếu bạn sử dụng hai đơn vị kiên trì khác nhau.

Mỗi đơn vị lưu giữ có thể chỉ định một bộ ánh xạ duy nhất (bao gồm cả tên bảng). Một cách để đạt được điều này là tạo hai tệp orm.xml. Trong persistence.xml bạn sẽ cần một cái gì đó như thế này:

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

Sau đó, trong vòng 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> 

Và trong vòng 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> 

Bạn sẽ cần phải tạo một EntityManagerFactory riêng biệt cho mỗi PersistenceUnit (có thể không phải là những gì bạn muốn), nhưng nếu bạn muốn sử dụng cùng một lớp trên các cơ sở dữ liệu khác nhau (với các tên bảng khác nhau) thì đây sẽ là một cách để đi.

18

Tạo một lớp trừu tượng (một lớp mẫu) với chú thích @MappedSuperclass sau đó mở rộng nó. Mỗi lớp mở rộng sử dụng các chú thích @table, @entity và không chứa gì ngoài một hàm tạo rỗng. Tất cả mã sẽ nằm trong lớp cha của bạn. Trên các phương pháp của bạn, hãy sử dụng các generics cho biết thực thể tham số của bạn mở rộng từ templateClass và không cần thay đổi mã nữa. Các ánh xạ thích hợp sẽ ở trong mỗi con bạn vượt qua.

Các vấn đề liên quan