有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

具有双向关系的java持久化嵌套实体(onetomany)

我正在创建一个Spring Boot web应用程序,该应用程序应该通过HTTP接收JSON文档,将其解析为相应的实体类,并持久化该对象。JSON是一个配方实例的表示,一个配方可以有多个与其关联的步骤对象

食谱。java

@Entity
public class Recipe {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    private String name;

    @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL)
    private Set<Step> steps;

    // Additional attributes, constructors, getters and setters omitted
}

一步。java

@Entity
public class Step {

    @Id
    @GeneratedValue
    private Long id;

    @NotNull
    private String name;

    @ManyToOne
    @JoinColumn(name = "RECIPE_ID")
    private Recipe recipe;

    // Additional attributes, constructors, getters and setters omitted
}

然而,当向应用程序发送以下JSON文档时,step对象中引用RECIPE_ID的外键是null,因此配方与其步骤之间没有连接

{
    "name": "Test recipe",
    "description": "Test description",
    "type": "Test",
    "cookingTime": 45,
    "preparationTime": 30,
    "thumbnail": "",
    "steps": [
        {
            "number": 1,
            "name": "First step",
            "content": "Test content",
            "image": ""
        },
        {
            "number": 2,
            "name": "Second step",
            "content": "Test content",
            "image": ""
        }
    ]
}

既然指定了CascadeType.ALL,嵌套的步骤对象是否也应该被持久化?此外,我使用RestController来处理请求,使用JpaRepository类来持久化


共 (2) 个答案

  1. # 1 楼答案

    在你的控制器中,你将不得不这样做

    for (Step step : recipe.getSteps()) {
        step.setRecipe(recipe);
    }
    

    你基本上错过了Step object中的back引用,当你发帖时它就是null

  2. # 2 楼答案

    您可以在@many一侧添加@JsonBackReference注释,在@OneToMany一侧添加@JsonManagedReference注释

    @Entity
    public class Recipe {
    
        @Id
        @GeneratedValue
        private Long id;
    
        @NotNull
        private String name;
    
        @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL)
        @JsonManagedReference("recipe_steps")
        private Set<Step> steps;
    
        // Additional attributes, constructors, getters and setters omitted
    }
    
    
    @Entity
    public class Step {
    
        @Id
        @GeneratedValue
        private Long id;
    
        @NotNull
        private String name;
    
        @ManyToOne
        @JoinColumn(name = "RECIPE_ID")
        @JsonBackReference("recipe_steps")
        private Recipe recipe;
    
        // Additional attributes, constructors, getters and setters omitted
    }