JPA là hoàn toàn có thể xử lý đề nghị của bạn, bởi vì xuất hiện chung ở cấp lớp trừu tượng và cho các lớp bê tông của bạn nó có chính xác một giá trị duy nhất cho mỗi lớp. Trong thực tế, JPA sẽ lưu trữ các lớp con của bạn trong một hoặc nhiều bảng, theo @InheritanceStrategy bạn đã chọn và sử dụng cơ chế khác nhau cho điều đó.
Bạn có thể tìm ra cho mình lý do tại sao trường hợp của bạn không phải là một vấn đề, lý luận về cách một ORM có thể tiết kiệm hai lớp trên DB:
- Bạn có thể lưu trữ MyStringClass và MyIntegerClass trong cùng một bảng, thêm một Discriminator cột để ORM, khi nó tải từ DB, biết constructor nên được gọi.
- Bạn có thể lưu trữ mọi phân lớp trong nhiều bảng hơn.
gì là không thể, ở phía bên kia, là để xác định một generic
@Entity
@Table(name = "MyGenericClass")
public class MyGenericClass<T> {
private T t;
public MyGenericClass(T t) {
this.t=t;
}
}
Lý do cho điều này là, tại thời gian biên dịch, T được "xóa" vì loại tẩy xoá. Nó được sử dụng tại thời gian biên dịch để xác minh chữ ký và tính chính xác của các loại, nhưng sau đó nó được biến thành một java.lang.Object bên trong JVM. Nếu bạn làm theo cho đến bây giờ, bạn sẽ có thể hiểu như sau:
- Trong trường hợp của bạn, mỗi lớp con cụ thể của AbstractMyClass có một kiểu T được định nghĩa cho tất cả các trường của lớp. Trong khi thông tin T không được giữ lại trong AbstractMyClass, nó vẫn được giữ lại và duy nhất bên trong các lớp con.
- Trong trường hợp thứ hai tôi đăng, mỗi trường hợp cụ thể có thể có của MyGenericClass có thể có giá trị khác nhau có thể cho T và do loại xóa thông tin này không được giữ lại.
* Lưu ý: trường hợp thứ hai không thể được JPA xử lý là hoàn toàn hợp lý và nếu bạn rơi vào trường hợp đó, bạn nên tự hỏi câu hỏi về thiết kế của mình. Generics là một công cụ tuyệt vời để thiết kế các lớp linh hoạt có thể xử lý các lớp khác theo kiểu an toàn, nhưng kiểu an toàn là một khái niệm ngôn ngữ lập trình không liên quan gì tới tính kiên trì.
Thêm: bạn có thể sử dụng javap để xem những gì thực sự là xóa. Cất chú thích khỏi MyGenericClass và biên dịch nó.
G:\>javac MyGenericClass.java
G:\>javap -p MyGenericClass
Compiled from "MyGenericClass.java"
public class MyGenericClass extends java.lang.Object{
private java.lang.Object t;
public MyGenericClass(java.lang.Object);
}
Bạn đang sử dụng triển khai nào? – JMelnik
Hibernate 3.6 với Oracle 10g làm cơ sở dữ liệu. Ngoài ra, tôi tạo ra các bảng thủ công bằng tay. – jaakko
Bạn đang cố gắng đạt được gì ở cấp thiết kế? Điểm của việc có một siêu lớp như thế nào? –