为什么休眠不在OneToMany的所有者端设置外键

Div*_*nto 5 java hibernate jpa jackson spring-boot

我有2个实体,医院和部门,部门通过Hospital_id引用其医院。

@Entity
public class Hospital {
    ...
    private Set<Department> departments;

    @OneToMany(mappedBy = "hospital", cascade = CascadeType.ALL)
    public Set<Department> getDepartments() {
        return departments;
    }
}

@Entity
public class Department {
    ...
    private Hospital hospital;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "hospital_id")
    public Hospital getHospital() {
        return hospital;
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用Rest API创建实体实例:

@RequestMapping("/create")
@ResponseBody Hospital create(@RequestBody Hospital hospital){
    hospital = hospitalService.save(hospital);

    return hospital;
}
Run Code Online (Sandbox Code Playgroud)

我发布json负载来创建医院:

{"name":"t-hospital", "departments":[{"name": "department1"}]}
Run Code Online (Sandbox Code Playgroud)

由于我使用SpringBoot,因此Jackson将自动将json有效内容解析为Java Object(此处是其医院和部门)。

保存医院后,我发现外键:部门中的“ hospital_id”未设置。

为什么会这样,如果可能,保存医院对象时如何设置外键?

AsS*_*iDe 5

在持久化实体之前,您应该始终在所有者端创建关联,因为所有者端负责创建关系。

修改您的代码如下(包含 Java 8 代码):

@RequestMapping("/create")
@ResponseBody Hospital create(@RequestBody Hospital hospital){

    hospital.getDepartments().forEach(department->department.setHospital(hospital));
    hospital = hospitalService.save(hospital);

    return hospital;
}
Run Code Online (Sandbox Code Playgroud)

在将实体转换为 json 时,您可能会遇到一个新问题,因为 Jackson 以递归方式序列化相关实体,并且您会收到 StackOverflow 错误。要解决此问题,请添加@JsonManagedReferencewith @OneToManyannotation 和@JsonBackReferencewith @ManyToOneannotation。

注意:@JsonManagedReference并且@JsonBackReference在新版本的 Jackson 中可用