[英]JPA One-to-One relation creates a non unique foreign key
我有以下實體:
@Entity
public class A {
// id, etc..
@OneToOne
private B b;
}
表a
已經存在,當我向其中添加新字段b
時,hibernate 執行以下操作:
alter table a add column b_id int8
alter table a add constraint FKg76mxqt8whi8t8p4i7el95910 foreign key (b_id) references b
如您所見,外鍵列b_id
不是唯一的。 為什么會這樣? 一對一關系不是意味着外鍵必須是唯一的嗎? 這也是我在單向一對一關系的 JPA 規范中發現的內容:
[...] 外鍵列與表 B 的主鍵類型相同,並且有一個唯一鍵約束。
為了使它工作,我必須顯式地將@JoinColumn(unique=true)
注釋添加到字段中。 為什么我必須明確地這樣做?
為了創建唯一約束,您必須創建一個完整的雙向OneToOne
關系。
這意味着您必須在Parent ( Owning ) 實體上添加@OneToOne
注釋,並在Child實體上添加@OneToOne(mappedBy="...")
。
這將在您的id列上創建一個唯一約束。
否則,您正在建模兩種不同的關系,而不是一種雙向關系; 因為沒有什么能阻止當前模型讓兩個孩子指向同一個父級。
@OneToOne 注釋的官方JavaDoc有更多關於附加參數和雙向關系建議的信息。
UPD: 鏈接到有關如何處理@OneToOne
關系的休眠規范:
這意味着在您的B
實體模型上,您應該為A
實體添加一個字段,並使用@OneToOne(mappedBy="b")
對其進行注釋,以使您的關系雙向且完整,限制對單個 Parent 的訪問並創建唯一約束.
我最近遇到了這個問題。 我的假設是@OneToOne
必須在外鍵上添加唯一約束。 但是休眠不會這樣做。
請參閱 hibernate 文檔中的這一部分。 單向映射和雙向映射都沒有添加唯一約束(從文檔中的查詢中可以看出)。 這意味着在添加具有相同外鍵的行時,hibernate 不會拋出異常。
盡管請注意,在雙向映射的情況下,hibernate 在獲取父實體(但不是子實體)時會進行唯一性檢查。 如果有多個子(擁有)實體引用正在獲取的同一個父實體,hibernate 會拋出org.hibernate.exception.ConstraintViolationException
。
解決方案是在您的孩子上添加@JoinColumn(unique = true, ...)
。 在表中插入具有非唯一外鍵的行時,這也會引發錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.