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: