So sánh sự khác nhau giữa @OneToOne với @ManyToOne Hibernate.
(Xem thêm: Hướng dẫn tự học Hibernate)
Quan hệ 1-1 và 1-n trong SQL
Ví dụ 1:
Quan hệ giữa item_detail với item là 1-1
DROP TABLE IF EXISTS `item`; CREATE TABLE `item` ( `id` int(11) NOT NULL, `name` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ); DROP TABLE IF EXISTS `item_detail`; CREATE TABLE `item_detail` ( `id` int(11) NOT NULL, `description` varchar(45) DEFAULT NULL, `vendor` varchar(45) DEFAULT NULL, `remark` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`), CONSTRAINT `item-detail` FOREIGN KEY (`id`) REFERENCES `item` (`id`) );
Trong mối quan hệ trên, item_detail mapping với item qua chính id của nó tức là item_detail và item có giá trị id giống nhau
Ví dụ 2:
Quan hệ giữa item_detail với item là 1-1
DROP TABLE IF EXISTS `item`; CREATE TABLE `item` ( `id` int(11) NOT NULL, `name` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ); DROP TABLE IF EXISTS `item_detail`; CREATE TABLE `item_detail` ( `id` int(11) NOT NULL, `item_id` int(11) DEFAULT NULL, `description` varchar(45) DEFAULT NULL, `vendor` varchar(45) DEFAULT NULL, `remark` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `item_id_UNIQUE` (`item_id`), CONSTRAINT `item-detail` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) );
Trong mối quan hệ trên, item_detail mapping với item qua column item_id của nó tức là item_detail.item_id và item.id có giá trị id giống nhau
Lưu ý, column item_id sẽ là UNIQUE KEY, tức là sẽ không xảy ra trường hợp có nhiều row trong item_detail có cùng giá trị item_id
Ví dụ 3:
Quan hệ giữa item_detail với item là n-1.
DROP TABLE IF EXISTS `item`; CREATE TABLE `item` ( `id` int(11) NOT NULL, `name` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ); DROP TABLE IF EXISTS `item_detail`; CREATE TABLE `item_detail` ( `id` int(11) NOT NULL, `item_id` int(11) DEFAULT NULL, `description` varchar(45) DEFAULT NULL, `vendor` varchar(45) DEFAULT NULL, `remark` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`), CONSTRAINT `item-detail` FOREIGN KEY (`item_id`) REFERENCES `item` (`id`) );
Ví dụ 3 khá giống với ví dụ 2, item_detail mapping với item qua column item_id nhưng item_id không phải là UNIQUE_KEY, tức là có thể nhiều row item_detail cùng mapping tới 1 item.
Như vậy điểm khác nhau cơ bản giữa quan hệ 1-1 (OneToOne) với n-1 (ManyToOne) đó là quan hệ 1-1 chỉ cho phép 1 bản ghi chỉ được tham chiếu bởi 1 bản ghi khác trong khi quan hệ n-1 thì cho phép nhiều bản ghi cùng tham chiếu tới 1 bản ghi.
@ManyToOne và @OneToOne trong Hibernate
Khi mapping ví dụ trên sang Hibernate ta sẽ có kết quả sau:
Trường hợp OneToOne 1-1:
@Entity
public class ItemDetail {
@OneToOne
@JoinColumn(name = "item_id")
// or @PrimaryKeyJoinColumn cho trường hợp dùng chung Id
private Item item;
Trường hợp ManyToOne n-1:
@Entity
public class ItemDetail {
@ManyToOne
@JoinColumn(name = "item_id")
private Item item;
2 trường hợp trên chỉ khác nhau ở annotation @OneToOne với @ManyToOne, nhưng khi insert sẽ khác nhau, ví dụ:
Item item = new Item(); ItemDetail itemDetail1 = new ItemDetail(); itemDetail1.setItem(item); ItemDetail itemDetail2 = new ItemDetail(); itemDetail2.setItem(item); save();
Đoạn code trên sẽ thành công với trường hợp ManyToOne
Nhưng với trường hợp OneToOne sẽ bị lỗi ConstraintViolationException do có nhiều hơn 1 ItemDetail tham chiếu tới 1 Item
________________
Okay, Done!
References: