首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JPA一对一关系创建了一个非唯一的外键。

JPA一对一关系创建了一个非唯一的外键。
EN

Stack Overflow用户
提问于 2020-02-25 14:16:26
回答 2查看 2.5K关注 0票数 5

我有一个折叠实体:

代码语言:javascript
运行
复制
@Entity
public class A {

  // id, etc..

  @OneToOne
  private B b;
}

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

代码语言:javascript
运行
复制
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)注释添加到字段中。我为什么要明明白白地这么做?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-25 16:04:45

双向@OneToOne

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

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

这将对id列创建一个唯一的约束。

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

官方@OneToOne注释的JavaDoc有更多关于附加参数的信息和关于双向关系的建议。

UPD:规格说明关于它如何处理@OneToOne关系:

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

在你的情况下

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

票数 3
EN

Stack Overflow用户

发布于 2020-09-19 20:05:06

我最近偶然发现了这个问题。我的假设是,@OneToOne必须对外键添加一个唯一的约束。但hibernate不会这么做的。

在hibernate文档中看到这个部分。单向映射和双向映射都不添加唯一约束(从文档中的查询可以看出)。这意味着hibernate在添加具有相同外键的行时不会抛出异常。

尽管注意到在双向映射的情况下,hibernate在获取父实体(而不是子实体)时会执行唯一性检查。如果有多个子实体(拥有权)实体引用被获取的同一个父实体,hibernate将抛出一个org.hibernate.exception.ConstraintViolationException

解决方案是在您的孩子身上添加@JoinColumn(unique = true, ...)。在表中插入具有非唯一外键的行时,这也会引发错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60396652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档