phiên bản ngắn cho vội vàng:cách tiếp cận tốt nhất để liên kết các loại thực thể đa dạng trong JPA
Có nhiều bảng/thực thể trong mô hình tên miền của tôi có cùng lĩnh vực (UUID). Có một bảng mà tôi cần liên kết các hàng/cá thể của các thực thể như vậy với các thực thể được quản lý bởi JPA khác. Nói cách khác, trường hợp của trường trong bảng liên kết đó sẽ không được biết trước. Hai cách tiếp cận tôi có thể nghĩ đến là:
- Sử dụng một thực thể trừu tượng và một chiến lược TABLE_PER_CLASS, hoặc
- sử dụng một
@MappedSuperClass
cửa hàng tên lớp của instance trong bảng liên kết là tốt, hoặc một cái gì đó tương tự cho phép tôi xác định logic để nhận được thể hiện thực tế từ bảng bên phải.
Cả hai đều có ưu điểm và nhược điểm về độ phức tạp và hiệu suất. Mà bạn tin là tốt nhất, có thể có một lựa chọn thứ ba, hoặc có bạn đã thử một cái gì đó như thế này trong quá khứ và sẽ tư vấn/mạnh mẽ cảnh báo chống lại?
Long phiên bản trong trường hợp bạn muốn nền hơn:
Tôi có một/mô hình đối tượng cơ sở dữ liệu trong đó nhiều loại có một lĩnh vực chung: nhận dạng duy nhất (UUID). Lý do cho điều này là trường hợp của các loại này có thể bị thay đổi. Các thay đổi theo mô hình lệnh và dữ liệu của chúng có thể được đóng gói và chính nó vẫn tồn tại. Hãy gọi sự thay đổi này là "đột biến". Nó phải có khả năng tìm ra những đột biến tồn tại trong cơ sở dữ liệu cho bất kỳ thực thể nào, và ngược lại, trên thực thể mà một đột biến được lưu trữ hoạt động.
Lấy đối tượng sau đây với UUIDs như một (rất đơn giản) ví dụ:
Để lưu trữ "đột biến", chúng tôi sử dụng một bảng/thực thể gọi là MutationHolder
. Để liên kết một đột biến với thực thể đích của nó, có MutationEntityLink
. Lý do duy nhất dữ liệu này không phải là trực tiếp trên MutationHolder
là bởi vì có thể có liên kết trực tiếp hay gián tiếp, nhưng đó là ít xung yếu ở đây vì vậy tôi rời nó ra:
Câu hỏi đặt ra đi xuống đến làm thế nào tôi có thể mô hình entity
trường trong MutationEntityLink
. Có hai cách tiếp cận mà tôi có thể nghĩ đến.
Cách thứ nhất là tạo một lớp có chú thích @Entity
có chú giải với trường UUID. Customer
, Contract
và Address
sẽ mở rộng. Vì vậy, nó là một chiến lược TABLE_PER_CLASS. Tôi cho rằng tôi có thể sử dụng loại này cho trường entity
, mặc dù tôi không chắc chắn. Tuy nhiên, tôi lo sợ điều này có thể có một hình phạt nghiêm trọng về hiệu suất vì JPA sẽ cần phải truy vấn nhiều bảng để tìm ra cá thể thực tế.
Cách thứ hai chỉ đơn giản là sử dụng @MappedSuperClass
và chỉ lưu trữ UUID cho một thực thể trong trường entity
của MutationEntityLink
. Để có được thực thể thực sự với UUID đó, tôi phải giải quyết nó theo chương trình. Thêm một cột bổ sung với tên lớp của thực thể, hoặc một cái gì đó khác cho phép tôi xác định nó hoặc dán nó vào một truy vấn JPQL sẽ làm. Điều này đòi hỏi nhiều công việc hơn nhưng có vẻ hiệu quả hơn. Tôi không thích viết mã một số lớp tiện ích hoặc thực hiện một số chú thích tùy chỉnh/phản chiếu nếu cần.
Câu hỏi của tôi là phương pháp nào trong số những phương pháp này có vẻ tốt nhất? Ngoài ra, bạn có thể có một đề nghị tốt hơn, hoặc thông báo tôi đang thiếu một cái gì đó; ví dụ, có thể có một cách để thêm một cột kiểu ngay cả với TABLE_PER_CLASS thừa kế để trỏ JPA vào bảng bên phải? Có lẽ bạn đã thử một cái gì đó như thế này và muốn cảnh báo tôi về nhiều vấn đề phát sinh.
Một số thông tin bổ sung:
- Chúng tôi tạo ra cấu trúc CSDL, vì vậy chúng tôi có thể thêm bất cứ điều gì chúng ta muốn.
- Một chiến lược kế thừa bảng duy nhất không phải là một tùy chọn. Các bảng phải duy trì riêng biệt. Đối với cùng một lý do, tham gia thừa kế dường như không phù hợp hoặc.
- Nhà cung cấp JPA là Hibernate và sử dụng những thứ không thuộc tiêu chuẩn JPA không phải là vấn đề.
Rất vui khi biết bạn đang thực sự sử dụng phương pháp đó. Nó cho thấy rằng nó khả thi. Tôi nghĩ rằng subclassing MutationEntityLink cho mỗi thực thể được ánh xạ sẽ rất bất tiện, do đó, một loại cột phân biệt âm thanh tốt nhất ngay bây giờ. –
@G_H có đó là lý do để quyết định chống lại các lớp con. – Thomas
Tôi thích ý tưởng của @Thomas về phân lớp MutationEntityLink cho mọi thực thể. Vì đó là một lớp kỹ thuật cung cấp liên kết giữa các đột biến và các thực thể của bạn, tôi sẽ đi cho kế thừa bảng đơn. Bảng sẽ có cột phân biệt đối xử của nó và một cột khóa ngoài cho mỗi thực thể. Bảng có thể không phải là biểu diễn thanh lịch nhất của mô hình miền của bạn, nhưng bạn có thể nhận được hiệu suất tốt từ đó. –