JPA 一对一关系创建非唯一外键

M.D*_*etz 5 java spring hibernate jpa

我有以下实体:

@Entity
public class A {

  // id, etc..

  @OneToOne
  private B b;
}
Run Code Online (Sandbox Code Playgroud)

该表a已经存在,当我向其中添加新字段b时,hibernate 执行以下操作:

alter table a add column b_id int8
alter table a add constraint FKg76mxqt8whi8t8p4i7el95910 foreign key (b_id) references b
Run Code Online (Sandbox Code Playgroud)

如您所见,外键列b_id不是唯一的。为什么会这样?一对一关系不是意味着外键必须是唯一的吗?这也是我在单向一对一关系的 JPA 规范中发现的内容:

[...] 外键列与表 B 的主键类型相同,并且有一个唯一键约束。

为了使其工作,我必须明确地将@JoinColumn(unique=true)注释添加到该字段。为什么我必须明确地这样做?

Mar*_*kyi 3

双向@OneToOne

为了创建唯一约束,您必须创建完整的双向OneToOne关系。

这意味着您必须在实体(拥有@OneToOne)上添加注释,并在子实体上添加注释。@OneToOne(mappedBy="...")

这将为您的id列创建唯一约束。

否则,您将建模两种不同的关系,而不是一种双向关系;因为没有什么可以阻止当前模型让两个子对象指向同一个父对象。

@OneToOne 注释的官方JavaDoc提供了有关附加参数的更多信息以及有关双向关系的建议。

UPD:链接到hibernate规范,了解它如何处理@OneToOne关系:

  1. 当使用双向 @OneToOne关联时,Hibernate 在获取子端时强制执行唯一约束。
  2. 单向关联遵循关系数据库外键语义,客户端拥有该关系。

在你的情况下

这意味着在您的B实体模型上,您应该添加一个带有A实体的字段并对其进行注释@OneToOne(mappedBy="b"),以使您的关系双向且完整,限制对单个父级的访问并创建唯一约束。