2013-04-20 74 views
25

Tôi đang đọc tài liệu về Hibernate về số entity associations và tôi gặp phải một chút khó khăn để tìm ra một số điều. Nó phải làm thực chất với sự khác biệt giữa các liên kết ManyToOneOneToMany. Mặc dù tôi đã sử dụng chúng trong các dự án thực sự, tôi không thể tóm được hoàn toàn sự khác biệt giữa chúng. Theo hiểu biết của tôi, nếu một bảng/một thực thể có một hiệp hội ManyToOne với một tổ chức khác, thì hiệp hội phải từ phía bên kia OneToMany. Vì vậy, làm thế nào chúng ta nên quyết định cái nào để lựa chọn dựa trên một trường hợp cụ thể và làm thế nào nó ảnh hưởng đến cơ sở dữ liệu/truy vấn/kết quả? Ở đó có một ví dụ hay không?Hibernate/JPA ManyToOne vs OneToMany

P .: Tôi nghĩ rằng nó sẽ hữu ích do sự liên quan của nó đối với câu hỏi, nếu ai đó bên cạnh có thể giải thích điểm của chủ sở hữu hiệp hội và sự khác biệt giữa liên kết hai hướng và một chiều.

Trả lời

43

Giả sử bạn có Đơn hàng và Đơn đặt hàng. Bạn có thể chọn để có OneToMany một chiều giữa Order và OrderLine (Order sẽ có một tập hợp các OrderLines). Hoặc bạn có thể chọn để có một liên kết ManyToOne giữa OrderLine và Order (OrderLine sẽ có một tham chiếu đến Order của nó). Hoặc bạn có thể chọn để có cả hai, trong trường hợp này, hiệp hội trở thành một liên kết OneToMany/ManyToOne hai chiều.

Giải pháp bạn chọn chủ yếu phụ thuộc vào tình huống và mức độ khớp nối giữa các thực thể. Ví dụ, nếu một người sử dụng, một công ty, một nhà cung cấp có nhiều địa chỉ, nó sẽ có ý nghĩa để có một hướng một chiều giữa mỗi người trong số họ và địa chỉ, và có địa chỉ không biết về chủ sở hữu của họ.

Giả sử bạn có một người dùng và một thông điệp, nơi người dùng có thể có hàng nghìn thư, có thể chỉ cần mô hình hóa nó như một ManyToOne từ Thư cho người dùng, vì bạn hiếm khi yêu cầu tất cả thư người dùng. Hiệp hội có thể được thực hiện hai chiều chỉ để giúp đỡ với các truy vấn mặc dù, kể từ khi truy vấn JPQL tham gia giữa các thực thể bằng cách điều hướng thông qua các hiệp hội của họ.

Trong liên kết hai chiều, bạn có thể ở trong tình huống mà đồ thị của đối tượng không nhất quán. Ví dụ, Order A sẽ có một tập hợp OrderLines trống, nhưng một số OrderLines sẽ có một tham chiếu đến Order A. JPA áp đặt để luôn luôn có một mặt của hiệp hội là bên chủ sở hữu, và phía bên kia là mặt nghịch đảo. Mặt nghịch đảo bị bỏ qua bởi JPA. Phía chủ sở hữu là bên quyết định mối quan hệ nào tồn tại. Trong một hiệp hội hai chiều OneToMany, phía chủ sở hữu phải là nhiều bên. Vì vậy, trong ví dụ trước, phía chủ sở hữu sẽ là OrderLine và JPA sẽ duy trì liên kết giữa các dòng và thứ tự A, vì các dòng có tham chiếu đến A.

Liên kết như vậy sẽ được ánh xạ như sau:

trong thứ tự:

@OneToMany(mappedBy = "parentOrder") // mappedBy indicates that this side is the 
    // inverse side, and that the mapping is defined by the attribute parentOrder 
    // at the other side of the association. 
private Set<OrderLine> lines; 

trong Hang:

@ManyToOne 
private Order parentOrder; 
1

Ngoài ra, có @ManytoOne bên là chủ sở hữu sẽ yêu cầu chỉ n + 1 q ueries trong khi lưu các associtions. Trong đó n là số lượng các hiệp hội (nhiều bên).

Trong khi có @OneToMany làm chủ sở hữu, trong khi chèn thực thể cha mẹ (một bên) với các liên kết (nhiều bên) sẽ dẫn đến 2 * N + 1 truy vấn. Trong đó một truy vấn sẽ được cho chèn của hiệp hội và truy vấn khác sẽ được cập nhật khóa nước ngoài trong thực thể liên quan.

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