Java JPA hibernate中一对一关系中的外键约束
我有两个具有一对一关系的实体Java JPA hibernate中一对一关系中的外键约束,java,mysql,spring,hibernate,jpa,Java,Mysql,Spring,Hibernate,Jpa,我有两个具有一对一关系的实体A和B。当我想将它们插入数据库时,会出现以下错误: 无法添加或更新子行:外键约束失败 (mydba,约束 FK_77pkrkrin5nqsx16b6nw6k9r7外键(id)引用 b(b\u id) 如果删除optional=false,插入操作将非常有效。在将对象插入数据库之前,我检查了它们,并确保A包含B和B包含A 创建A和B的SQL脚本包括: Hibernate:创建表b(b_id整数非空自动增量, 字符串\结果长文本,a\ id整数,主键(b\ id)) Hi
A
和B
。当我想将它们插入数据库时,会出现以下错误:
无法添加或更新子行:外键约束失败
(mydb
a
,约束
FK_77pkrkrin5nqsx16b6nw6k9r7
外键(id
)引用
b
(b\u id
)
如果删除optional=false
,插入操作将非常有效。在将对象插入数据库之前,我检查了它们,并确保A
包含B
和B
包含A
创建A
和B
的SQL脚本包括:
Hibernate:创建表b(b_id整数非空自动增量,
字符串\结果长文本,a\ id整数,主键(b\ id))
Hibernate:创建表a(id整数非空自动增量,主
钥匙(id))
休眠:更改表b添加约束FK_O3OEN721ETLDC7LS82524NH
外键(详细信息_id)引用a(id)
休眠:更改表a添加约束FK_77pkrkrin5nqsx16b6nw6k9r7
外键(id)引用b(b_id)
从hibernate文档: (可选)关联是否可选。如果设置为false,则必须始终存在非null关系 就在创建B时,B_id不可用,它是在数据库发生刷新时创建的 由于A在B上有一个外键关系(B_id),因此在插入A或将此外键关系标记为可选关系之前,需要将B与其id一起创建
创建B并将其刷新到数据库,然后创建A。B有A不是必需的,因为它的A为B定义了外键,反之亦然,B对A的引用只是自反的,双向外键将创建循环引用问题。当我看到以下句子时: 在将对象插入数据库之前,我检查了它们,并确保A包含B,B包含A 我猜你想建立一种双向的一对一关系。如果是这样,则当前映射无法按预期工作。让我们看看(下载链接)对此有何说明,以了解问题: 关系可以是双向的,也可以是单向的。双向关系既有拥有方也有反向(非拥有方)。单向关系只有一个拥有方。关系的拥有方确定数据库中关系的更新,如第3.2.4节所述 以下规则适用于双向关系: •双向关系的反向侧必须通过使用OneToOne、OneToMany或ManyToMany注释的mappedBy元素来指代其所属侧。mappedBy元素指定实体中作为关系所有者的属性或字段 •一对多/多对一双向关系的多方必须是拥有方,因此不能在manytone注释上指定mappedBy元素 •对于一对一的双向关系,拥有方对应于包含相应外键的方 •对于多对多双向关系,任何一方都可能是拥有方 因此,根据双向一对一关系中的规范,必须使其中一个实体成为拥有方,另一个实体成为反向方。假设实体
A
是拥有方,以下映射应该有效:
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
@JoinColumn(name="b_id", referencedColumnName="ID")
private B b;
}
@Entity
public class B {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@OneToOne(mappedBy = "b")
private A a;
}
为了使上述映射工作,必须自动生成物理表,或者如果您想自己创建表,则相应的SQL应该如下所示:
create table a (id integer not null auto_increment,
b_id integer not null,
primary key (id),
foreign key b_id references b (id));
create table b (id integer not null auto_increment,
string_results longtext,
primary key (id));
注:
B
成为拥有方,则必须相应地调整关系映射
@JoinColumn
注释始终位于所有者一侧
你的数据库是什么?是oracle吗?@ArifAcar Google MySQL您确定您的映射正确吗?查看您的实体,我可以说这两个表中的主键字段都被称为
ID
以及BID
<代码>B_ID未映射。首先检查映射是否正确,或者发布数据库创建脚本以及创建和保存实体的代码段。@ujulu我添加了数据库创建脚本。我认为这不可行。您正在使用@heritation
,但这两个实体都不是另一个实体的子类。此外,表的两侧都有外键定义;我认为您必须决定哪个表应该包含外键。不幸的是,我现在没有时间。如果到那时还没有人回答,我今天晚上就去看。但在那之前,你必须决定哪个表是父表。实际上,B在A上有外键。
create table a (id integer not null auto_increment,
b_id integer not null,
primary key (id),
foreign key b_id references b (id));
create table b (id integer not null auto_increment,
string_results longtext,
primary key (id));