2011-09-11 33 views
7

Trong một dự án dựa trên Spring/Hibernate, chúng tôi có mối quan hệ một-nhiều giữa hai thực thể. Các hoạt động bắt buộc là:Có nên tránh các liên kết hai chiều Hibernate?

  • tìm cha mẹ của đứa trẻ;
  • tìm con của cha mẹ;
  • khi cha mẹ bị xóa, chúng tôi cũng cần xóa con;
  • tạo hàng loạt trẻ em.

Chúng tôi đã đưa ra hai cách để thực hiện việc này.

  1. Bidirectional association: thực thể con có @ManyToOne cột liên kết nó với cha mẹ, và phụ huynh có @OneToMany bộ sưu tập lười biếng-nạp của trẻ em. Tất cả các hoạt động trên có thể được thực hiện trong các mô hình:

    child.getParent(); 
    parent.getChildren(); //lazy loading 
    session.delete(parent); //cascade removal of the children does the trick here 
    session.save(parent); //cascade persist created the children 
    
  2. Unidirectional hiệp hội: thực thể con có @ManyToOne cột liên kết nó với cha mẹ, nhưng phụ huynh không có bất kỳ liên kết đến trẻ em. Hầu hết các hoạt động sẽ được thực hiện trong các phương pháp dịch vụ:

    child.getParent(); //still in the model 
    Collection<Child> findChildren(Parent parent); //service method in ChildService 
    void deleteChildren(Parent parent); //service method in ChildService 
    void createChild(Parent parent, ... childAttributes); //service method in ChildService invoked for each new child. 
    

Phương pháp đầu tiên có vẻ là dễ dàng hơn để thực hiện (bạn có thể tái sử dụng Hibernate chức năng tầng) nhưng một số người trong chúng ta thấy các hiệp hội hai chiều như một nguyên nhân tiềm ẩn của các vấn đề .

Điều gì sẽ là lựa chọn thiết kế tốt hơn? Có bất kỳ vấn đề, hiệu suất hay thiết kế nổi tiếng nào, được tạo ra bởi phương pháp hai chiều không?

+0

Bạn có biết nguồn nào giải thích cách làm việc lười biếng không? Tôi đã gặp rắc rối với điều này trong một dự án JSF. –

+1

"một số người trong chúng ta thấy các hiệp hội hai chiều là một nguyên nhân tiềm ẩn của các vấn đề" - bạn có thể đặt tên cho những vấn đề tiềm năng này không? –

Trả lời

3

Nếu truy vấn của bạn thực hiện tương tự như các truy vấn được thực hiện đằng sau cảnh Hibernate khi nó tải trẻ em xuống, tôi không thấy bạn đạt được điều gì bằng cách không đơn giản sử dụng liên kết OneToMany.

Nếu bạn biết mình đang làm gì và mỗi phương thức gọi trên thực thể của bạn có nghĩa là gì về truy vấn cơ sở dữ liệu, bạn sẽ không gặp bất kỳ vấn đề nào với bộ sưu tập được ánh xạ. Đôi khi nó là khôn ngoan để đi qua chúng, đôi khi nó tốt hơn để sử dụng một truy vấn đặc biệt để tránh quá nhiều chuyến đi vòng đến cơ sở dữ liệu. Điều quan trọng là hiểu điều gì xảy ra.

Có một phân ly cũng có thể rất hữu ích chỉ để có thể điều hướng qua nó trong các truy vấn HQL, không nhất thiết phải gọi hàm getter liên quan.

0

Miễn là bạn đang ở trong tình huống tải xuống thực sự hiệu quả với bạn, tôi chưa từng thấy vấn đề thực sự với các mối quan hệ hai chiều. Tôi đã từng làm việc trên một ứng dụng Flex nơi Hibernate được sử dụng và các mối quan hệ hai chiều thường sẽ làm cho toàn bộ cơ sở dữ liệu được tải xuống khi dữ liệu được tuần tự hóa cho máy khách.

YMMV

0

Câu trả lời bởi @JB Nizet nói nó gần như tất cả, chỉ cần một điều nữa: Nhìn vào mẫu gọi phương thức bạn được đăng, phương pháp hai chiều có thể sẽ làm cho mã logic kinh doanh của bạn một chút dễ đọc hơn.

-1

Có, Điều đó cần tránh càng nhiều càng tốt. nếu bạn thực sự nghĩ, đó là yêu cầu của bạn, thì chỉ sử dụng hai chiều. ví dụ. Emp và Dept, mỗi emp có một bộ phận, nhưng bộ phận có nhiều nhân viên. emp phải biết về bộ phận của mình, nhưng nó không phải là bắt buộc rằng, bộ phận cũng nên biết bộ phận của họ.

+1

Điều này có vẻ giống một bình luận hơn là một câu trả lời. – mattias

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