Tại sao khái niệm về một bên sở hữu là cần thiết:
Ý tưởng về một khía cạnh sở hữu của mối quan hệ hai chiều xuất phát từ thực tế là trong các cơ sở dữ liệu quan hệ không có quan hệ hai chiều như trong trường hợp của các đối tượng. Trong cơ sở dữ liệu chúng ta chỉ có quan hệ một chiều - khóa ngoại.
Lý do cho cái tên 'bên sở hữu' là gì?
Phía sở hữu của mối quan hệ được theo dõi bởi Hibernate là phía của mối quan hệ sở hữu khóa ngoại trong cơ sở dữ liệu.
Vấn đề mà khái niệm sở hữu bên giải quyết là gì?
Lấy một ví dụ về hai thực thể được ánh xạ mà không cần khai báo một bên sở hữu:
@Entity
@Table(name="PERSONS")
public class Person {
@OneToMany
private List<IdDocument> idDocuments;
}
@Entity
@Table(name="ID_DOCUMENTS")
public class IdDocument {
@ManyToOne
private Person person;
}
Từ quan điểm OO, ánh xạ này xác định không phải là một mối quan hệ hai chiều, mà là hai mối quan hệ đơn hướng riêng biệt.
Ánh xạ sẽ tạo ra không chỉ các bảng PERSONS
và ID_DOCUMENTS
, mà còn tạo ra một bảng kết hợp thứ ba PERSONS_ID_DOCUMENTS
:
CREATE TABLE PERSONS_ID_DOCUMENTS
(
persons_id bigint NOT NULL,
id_documents_id bigint NOT NULL,
CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id),
CONSTRAINT fk_docs FOREIGN KEY (id_documents_id) REFERENCES id_documents (id),
CONSTRAINT pk UNIQUE (id_documents_id)
)
Chú ý khóa chính pk
trên ID_DOCUMENTS
chỉ. Trong trường hợp này, Hibernate theo dõi cả hai mặt của mối quan hệ một cách độc lập: Nếu bạn thêm một tài liệu vào quan hệ Person.idDocuments
, nó sẽ chèn một bản ghi vào bảng kết hợp PERSON_ID_DOCUMENTS
.
Mặt khác, nếu chúng ta gọi idDocument.setPerson(person)
, chúng ta sẽ thay đổi người nước ngoài person_id trên bàn ID_DOCUMENTS
. Hibernate đang tạo hai quan hệ một chiều (khóa ngoại) trên cơ sở dữ liệu, để thực hiện một quan hệ đối tượng hai chiều.
Làm thế nào khái niệm sở hữu bên giải quyết vấn đề:
Nhiều lần những gì chúng tôi muốn chỉ là một khoá ngoại trên bảng ID_DOCUMENTS
hướng PERSONS
và bảng gắn thêm.
Để giải quyết vấn đề này, chúng ta cần cấu hình Hibernate để ngừng theo dõi các sửa đổi về mối quan hệ Person.idDocuments
. Hibernate chỉ nên theo dõi khác bên của mối quan hệ IdDocument.person
, và làm như vậy chúng ta thêm mappedBy :
@OneToMany(mappedBy="person")
private List<IdDocument> idDocuments;
Nó có nghĩa là mappedBy?
Điều này có nghĩa đại loại như: "các sửa đổi ở phía bên này của mối quan hệ đã được ánh xạ Ở
phía bên kia của mối quan hệ IdDocument.person, vì vậy không cần phải theo dõi riêng ở đây trong một bảng phụ."
Có bất kỳ GOTCHA, hậu quả?
Sử dụng mappedBy , Nếu chúng tôi chỉ gọi person.getDocuments().add(document)
, khóa ngoại ID_DOCUMENTS
sẽ KHÔNG được liên kết với tài liệu mới, vì đây không phải là phía sở hữu / theo dõi của mối quan hệ!
Để liên kết tài liệu với người mới, bạn cần gọi một cách rõ ràng document.setPerson(person)
, vì đó là khía cạnh sở hữu của mối quan hệ.
Khi sử dụng mappedBy , nhà phát triển có trách nhiệm phải biết phía sở hữu là gì và cập nhật phía chính xác của mối quan hệ để kích hoạt tính bền vững của mối quan hệ mới trong cơ sở dữ liệu.