簡體   English   中英

JPA 一對一關系創建非唯一外鍵

[英]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

為了創建唯一約束,您必須創建一個完整的雙向OneToOne關系。

這意味着您必須在Parent ( Owning ) 實體上添加@OneToOne注釋,並在Child實體上添加@OneToOne(mappedBy="...")

這將在您的id列上創建一個唯一約束。

否則,您正在建模兩種不同的關系,而不是一種雙向關系; 因為沒有什么能阻止當前模型讓兩個孩子指向同一個父級。

@OneToOne 注釋的官方JavaDoc有更多關於附加參數和雙向關系建議的信息。

UPD: 鏈接到有關如何處理@OneToOne關系的休眠規范

  1. 當使用雙向@OneToOne關聯時,Hibernate 在獲取子端時強制執行唯一約束。
  2. 單向關聯遵循關系數據庫外鍵語義,客戶端擁有關系。

在你的情況下

這意味着在您的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM