Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA hibernate中一对一关系中的外键约束_Java_Mysql_Spring_Hibernate_Jpa - Fatal编程技术网

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));
注:

  • 我删除了特定于JSON的注释以缩短代码(我对它们一无所知)

  • 如果要使实体
    B
    成为拥有方,则必须相应地调整关系映射

  • @JoinColumn
    注释始终位于所有者一侧

  • 由于时间不够,我还没有测试代码。如果您发现任何bug(特别是MySQL语法),请给我留言


  • 你的数据库是什么?是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));