2011-12-20 34 views
7

Mặc dù câu hỏi của tôi được diễn giải cụ thể theo cách các mối quan hệ thực thể được mô tả trong khung chơi, sử dụng Hibernate, tôi chắc chắn đây là một khái niệm.Cố gắng hiểu tầm quan trọng của một bên sở hữu mối quan hệ một-nhiều trong ORM

Khi chúng tôi có mối quan hệ một-nhiều, chúng tôi luôn được yêu cầu chỉ định bên sở hữu.

Vì vậy, ví dụ: nếu chúng tôi có mối quan hệ một-nhiều giữa Người và PhoneNumber, chúng tôi sẽ viết mã như thế này.

@Entity 
class Person { 
    @OneToMany(mappedBy="person") 
    public Set<PhoneNumber> phoneNumbers; 
} 

@Entity 
class PhoneNumber { 
    @ManyToOne 
    public Person person; 
} 

Trong mã ở trên, chủ sở hữu là PhoneNumber. Những ưu và khuyết điểm của hai bên là thực thể sở hữu là gì?

Tôi nhận ra khi thực thể sở hữu là PhoneNUmber, mối quan hệ được biểu thị là ManyToOne, sẽ không kết quả trong bảng nối, trong khi khi bên sở hữu là Person, mối quan hệ được mô tả sẽ là OneToMany. được tạo ra.

Đây có phải là lý do chính để xác định bên sở hữu hoặc có các lý do khác không?

Cập nhật: Tôi vừa nhận ra rằng this thread cung cấp một phần câu trả lời, nhưng tôi hy vọng cũng có thể có các điểm khác.

Trả lời

1

Với hầu hết các lớp ORM, bạn có khái niệm tải chậm. Khi bạn tạo một đối tượng Person, nó sẽ không tải các thiết lập điện thoại trừ khi được yêu cầu. Đôi khi, cách bạn muốn tra cứu dữ liệu cũng có thể quyết định cách bạn lưu trữ dữ liệu đó.

Giống như nếu bạn muốn đưa người lên trước và sau đó hiển thị số điện thoại theo yêu cầu thì việc giữ người tham chiếu trong điện thoại vẫn ổn. Trước tiên, bạn kích hoạt một truy vấn đơn giản để tải dữ liệu người và sau đó chỉ cần tra cứu số điện thoại dựa trên person.id (đã được tải) person.id (một truy vấn đơn giản khác)

Trong khi hiển thị dữ liệu người + điện thoại cùng một lúc, bạn muốn có một bảng tham gia mà bạn chỉ có thể tải dữ liệu dựa trên bảng người + người-điện thoại tham gia bảng sử dụng id người như các phím vào bảng điện thoại, tất cả trong một đi. Ở đây nó sẽ là tốn kém để làm tra cứu mà không có một bảng quan hệ.

Nhưng khá thẳng thắn, nếu bạn nghĩ rằng SQL thay vì ORM sau đó bạn sẽ đi với một bảng mối quan hệ mỗi lần: D

+0

Tôi đang cố gắng suy nghĩ to. Giả sử trong cả hai trường hợp, chúng tôi thực hiện tìm nạp háo hức. Đối với trường hợp đầu tiên, trong đó PhoneNumber là thực thể sở hữu, chúng tôi sẽ kích hoạt truy vấn đầu tiên để nhận tất cả các thực thể Person và sau đó kích hoạt các truy vấn riêng lẻ cho từng Người để nhận tất cả PhoneNumber cho Người đó. Tuy nhiên, nếu chúng ta có Person là bên sở hữu, chúng ta chỉ cần kích hoạt một truy vấn có tham gia. Tôi xin lỗi nếu đây là một câu hỏi ngớ ngẩn, nhưng là một tham gia không thể với Người là một FK trong PhoneNumber? – Parag

+0

Có, tham gia sẽ có thể với người id FK trong bảng điện thoại là tốt.Ở đây tôi (giả định) rằng một tra cứu bình thường sẽ nhanh hơn nhưng bạn phải xem xét kế hoạch giải thích của bạn để chắc chắn. Một lý do khác (ít nhất là lý thuyết) để sử dụng một bảng quan hệ sẽ cho phép chia sẻ các số điện thoại, giống như một số điện thoại được sử dụng bởi hai người trong ca. Thành thật mà nói, Làm thế nào một lớp ORM hoạt động nên không quan trọng cho những cân nhắc như vậy bởi vì không ai thiết kế lược đồ với lớp ORM trong tâm trí – rjha94

+0

xem câu trả lời của tôi trong chủ đề này cũng như vì lý do tên 'mappedBy' và 'owning side' nếu chúng tôi không xác định một bên sở hữu, GOTCHAs - http://stackoverflow.com/questions/2749689/what-is-the-owning-side-in-an-orm-mapping/21068644#21068644 –

6

Một điểm quan trọng cần lưu ý là các mối quan hệ sở hữu là một trong đó thực sự tồn tại các quan hệ về tiết kiệm. Với ví dụ:

Person person = new Person(); 
    PhoneNumber pn = new PhoneNumber(); 
    pn.phone = "12345678"; 
    person.phoneNumbers.add(pn); 
    session.save(person); 

Quan hệ không được lưu nếu bạn tải lại thực thể từ cơ sở dữ liệu mà bạn sẽ thấy không có số. Để thực sự thêm mối quan hệ bạn cần đặt người ở bên chủ sở hữu (PhoneNumber) và sau đó lưu.

// the relation is not saved 
    Person loadedPerson = (Person)session.load(Person.class, person.id); 
    System.out.println(loadedPerson.phoneNumbers.size()); // prints 0! 

    pn.person = person; 
    session.save(pn); 

    loadedPerson = (Person)session.load(Person.class, person.id); 
    System.out.println(loadedPerson.phoneNumbers.size()); // prints 1 
Các vấn đề liên quan