Spring Data JPA 使用父对象的 ID 保存子对象

问题描述

我有两个对象,一个父对象和一个子对象,如下所示:

@Entity
@Table(name="category")
public class CategoryModel {
    private @Id @GeneratedValue Long id;

    private String name;

    @OnetoMany(mappedBy="category",cascade=CascadeType.PERSIST)
    private List<AttributeModel> attributes;
}

@Entity
@Table(name="attribute")
public class AttributeModel {
    private @Id @GeneratedValue Long id;

    private String name;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="category_id")
    private CategoryModel category;
}

我也有映射到这些模型对象的 dtos,但我忽略了它们。 当我尝试使用此有效负载保存类别对象时,属性值也在属性表中创建,但具有 null 类别 ID。

{
    "name":"Chemicals","attributes":[
        {"name": "volume"},{"name":"humidity"}
    ]
}

如何将我的属性值与在它们之前创建的类别 ID 一起保存到数据库中?

解决方法

首先,这个问题不是“Spring Data JPA”问题,而是JPA(可能是Hibernate)问题。


分析

由于您省略了控制器和 JSON 映射的代码,我不得不猜测一下:

  • 事实 1:categoryattributes 之间的关系由属性 AttributeModel.category 控制,而不是由 CategoryModel.attributes 控制。 (这就是 JPA 的工作方式。
  • 观察 2:您的 JSON 对象定义了 CategoryModel.attributes(即与 JPA 的工作方式相反)。

在不知道您的 JSON 映射配置和控制器代码的情况下,我会猜测问题是:您的 JSON 映射器在反序列化 JSON 时没有设置 AttributeModel.category 字段对象。


解决方案

因此您需要在反序列化期间指示 JSON 映射器设置 AttributeModel.category 字段。如果您使用 Jackson,则可以使用:

  • @JsonManagedReference
  • @JsonBackReference
@Entity
@Table(name="category")
public class CategoryModel {
    ...    

    @JsonManagedReference
    @OneToMany(mappedBy="category",cascade=CascadeType.PERSIST)
    private List<AttributeModel> attributes;
}
@Entity
@Table(name="attribute")
public class AttributeModel {
    ...

    @JsonBackReference
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="category_id")
    private CategoryModel category;
}
,

我通过手动设置子对象对父对象的引用解决了这个问题:

public Long createCategory(CategoryDto categoryDto) {
    CategoryModel categoryModel = categoryDto.toModel(true,true);
    categoryModel.getAttributes().forEach(a -> a.setCategory(categoryModel));
    return categoryRepository.save(categoryModel).getId();
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...