我有两个实体 A
和 B
与一对一的关系 . 当我想将它们插入数据库时,我收到以下错误:
无法添加或更新子行:外键约束失败(mydb.a,CONSTRAINT FK_77pkrkrin5nqsx16b6nw6k9r7 FOREIGN KEY(id)REFERENCES b(b_id))
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true, value={"hibernateLazyInitializer", "handler"})
@Generated("org.jsonschema2pojo")
@Inheritance(strategy = InheritanceType.JOINED)
@Entity
public class A {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@JsonIgnore
private Integer id;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
@PrimaryKeyJoinColumn(referencedColumnName="AId")
@JsonIgnore
private B b;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true, value = {"hibernateLazyInitializer", "handler"})
@Generated("org.jsonschema2pojo")
@Entity
public class B {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int bId;
@OneToOne()
@JsonIgnore
private A a;
}
如果我删除 optional=false
,插入操作将完美地工作 . 我在将对象插入数据库之前检查了对象,并确保 A
包含 B
和 B
包含 A
.
A
和 B
创建的SQL脚本是:
Hibernate:创建表b(b_id整数不为null auto_increment,string_results longtext,a_id整数,主键(b_id))Hibernate:create table a(id integer not null auto_increment,primary key(id))Hibernate:alter table b add constraint FK_o3oen721etlltdc7ls82524nh外键(detail_id)引用一个(id)Hibernate:alter table一个添加约束FK_77pkrkrin5nqsx16b6nw6k9r7外键(id)引用b(b_id)
2 回答
来自hibernate的文档:
在创建B时,b_id不可用,它是在数据库发生刷新时创建的 .
由于A在B(b_id)上具有外键关系,因此在插入A或将此外键关系标记为可选之前,需要创建B及其id .
创建B并将其刷新到数据库,然后创建A. B不需要A作为其A定义B的外键而不反之亦然,B对A的引用只是反身,双向外键将创建循环参考问题 .
当我看到以下句子时:
我想你想创建一个双向的一对一关系 . 如果是这样,您当前的映射无法按预期工作 . 让我们看一下JPA 2.0 spec(下载链接)说明了解这个问题:
因此,根据规范,双向一对一关系中的一个实体必须成为拥有方,而另一个实体必须是反方 . 假设实体
A
是以下映射应该起作用的拥有方:为了使上述映射工作或者必须自动生成物理表,或者如果您想自己创建表,相应的SQL应该如下所示:
注意:
我删除了特定于JSON的注释以使代码更短(我对它们没有任何了解)
如果要使实体
B
成为拥有方,则必须相应地调整关系映射 .@JoinColumn
注释总是在拥有方 .由于时间不够,我没有测试过代码 . 如果您发现任何错误(尤其是MySQL语法),请给我留言 .