我正在使用SPRING DATA JPA,我有以下实体:
public class EntityA {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SOME_SEQ")
@SequenceGenerator(sequenceName = "SOME_SEQ", allocationSize = 1, name = "SOME_SEQ")
private Long id;
private String name;
@OneToOne(mappedBy = "entityBField", cascade = CascadeType.ALL)
private EntityB entityB;
}
public class EntityB {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SOME_OTHER_SEQ")
@SequenceGenerator(sequenceName = "SOME_OTHER_SEQ", allocationSize = 1, name = "SOME_OTHER_SEQ")
private Long id;
private Integer type;
@OneToOne
@JoinColumn(name = "entityaId", referencedColumnName = "id")
private EntityA entityBField;
}
表的定义:
create table EntityA(
id int primary key,
name varchar(255)
);
create table EntityB(
id int primary key,
type int,
entitya_Id int FOREIGN KEY ("entitya_Id")
REFERENCES "EntityA" ("id")
);
我创建并保存一个实例,如下所示:
EntityA a = new EntityA();
EntityB b = new EntityB();
a.setEntityB(b);
entityARepository.save(a)
发生的是entityA和entityB都被持久化,但是entityB上的外键entityaId为空。你能建议我如何保存连接EntityB到EntityA的外键吗?
您需要实现方法EntityA。settentityb:
public class EntityA {
public void setEntityB(EntityB entityB) {
if (entityB == null) {
if (this.entityB != null) {
this.entityB.setEntityBField(null);
}
}
else {
entityB.setEntityBField(this);
}
this.entityB = entityB;
}
}
EntityB。setEntityBField应该是通常的setter:
public class EntityB {
public void setEntityBField(EntityA entityBField) {
this.entityBField = entityBField;
}
}
另外,您可能需要"optional = false"在注释中:
@OneToOne(mappedBy = "entityBField", cascade = CascadeType.ALL, optional = false)
private EntityB entityB;
参见本文中的示例:https://vladmihalcea.com/the-best-way-to-map-a-onetoone-relationship-with-jpa-and-hibernate/
注意:
mappedBy = "entityBField"
表示
EntityB.entityBField
负责管理一对一关系,
所以当你创建EntityB b = new EntityB()
和设置a.setEntityB(b)
,那么b.entityBField
是空的,当你做级联保存:entityARepository.save(a)
这就是为什么b.entityBField
(外键"entitya_Id")在数据库中为空。
通过在EntityA中实现正确的setter,您可以帮助JPA理解,entityB.entityBField
应该被设置为EntityA的主键(entityB.setEntityBField(this)
)
最简单的解决方案是这样的:
EntityA a = new EntityA();
EntityB b = new EntityB();
b.setEntityBField(a);
entityARepository.save(a)
你唯一需要做的改变是下面这行:
b.setEntityBField(a);