【发布时间】:2018-12-26 15:38:00
【问题描述】:
我有一个 Java API(使用 Spring Framework),我的前端使用它来创建新的父对象 (json),其中包含新的子对象列表,如下所示:
parent = {
children: [
{
childName: 'name1'
},
{
childName: 'name2'
}]
}
您可以看到没有 ID,因为我要保存它们,并且数据库应该生成 ID。
Parent 实体在后端有这段代码:
@OneToMany(cascade = {CascadeType.ALL}, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "parent")
private Set<Child> children = new HashSet<>();
在父级上调用存储库“保存”操作后,我可以在数据库中找到子元素(因此级联工作),但数据库中子级的“parentId”列为空,因此当我获取父级,其子级列表显示为空。
我可以通过在我的服务类中做这样的事情来解决这个问题:
repository.save(parent);
parent.getChildren().forEach((child) -> child.setParent(parent));
它之所以有效,是因为(我猜)到那时,父表已经有一个数据库为其生成的 ID,因此子表可以将该 ID 用于其 parentId 列。它可以工作,但感觉这应该是标准的一对多关系,并且应该由框架以比这更漂亮的方式自动处理。所以我的问题是:我错过了什么?
在 Cascade 操作期间保存子实体“parentId”列时,Hibernate 是否可以通过某种方式自动填充它们?
编辑: 这实际上可能是由我用来将 DTO 映射到 POJO 并返回的 MapStruct 引起的。还不确定,但会继续调查(见相关链接:https://github.com/mapstruct/mapstruct/issues/1068)
【问题讨论】:
-
你的猜测是错误的。该实体不存储父级的 ID。它存储对父对象的引用。您可以在保存父级之前执行此操作。但是你必须这样做:这是你的责任,而不是 JPA 的。按规范。
-
你能在子类中显示你的注释来引用父类吗?您是在子级还是父级上调用保存操作?
-
@Rohit 我保存了父级。 JBNizet 我的意思是子数据库表使用 parent.id 存储父表的外键,但我知道,就像你说的,Java 类具有对整个父对象的引用。我已尝试澄清我的帖子,抱歉。
标签: java spring hibernate jhipster mapstruct