我有一个折叠实体:
@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)注释添加到字段中。我为什么要明明白白地这么做?
发布于 2020-02-25 16:04:45
双向@OneToOne
为了创建唯一的约束,您必须创建一个完整的双向OneToOne关系。
这意味着您必须在@OneToOne父 (Owning)实体上添加@OneToOne(mappedBy="...")注释,并在@OneToOne(mappedBy="...")实体上添加@OneToOne(mappedBy="...")。
这将对id列创建一个唯一的约束。
否则,您将建模两种不同的关系,而不是一种双向关系;因此,没有什么可以阻止当前模型中有两个子程序指向同一个父类。
官方@OneToOne注释的JavaDoc有更多关于附加参数的信息和关于双向关系的建议。
UPD:规格说明关于它如何处理@OneToOne关系:
在你的情况下
这意味着,在您的B实体模型上,您应该添加一个带有A实体的字段,并使用@OneToOne(mappedBy="b")对其进行注释,以使您的关系双向和完整,从而限制对单亲的访问,并创建唯一的约束。
发布于 2020-09-19 20:05:06
我最近偶然发现了这个问题。我的假设是,@OneToOne必须对外键添加一个唯一的约束。但hibernate不会这么做的。
在hibernate文档中看到这个部分。单向映射和双向映射都不添加唯一约束(从文档中的查询可以看出)。这意味着hibernate在添加具有相同外键的行时不会抛出异常。
尽管注意到在双向映射的情况下,hibernate在获取父实体(而不是子实体)时会执行唯一性检查。如果有多个子实体(拥有权)实体引用被获取的同一个父实体,hibernate将抛出一个org.hibernate.exception.ConstraintViolationException。
解决方案是在您的孩子身上添加@JoinColumn(unique = true, ...)。在表中插入具有非唯一外键的行时,这也会引发错误。
https://stackoverflow.com/questions/60396652
复制相似问题