使用@EmbededId

时间:2017-01-15 23:28:27

标签: java jpa spring-boot

目标:使用@EmbededId来强制使用@Entity,其中id是复合主键。

问题:根据我当前的实施情况,我得到以下结果:

[
  {
    "id": 1,
    "name": "Recipe 1",
    "instruction": "Test Instruction",
    "note": "Note 1",
    "show": true,
    "createDate": null,
    "modify_date": null,
    "ingredient": [
      {},
      {}
    ]
  }
]

但我想要这个:

[
  {
    "id": 1,
    "name": "Recipe 1",
    "instruction": "Test Instruction",
    "note": "Note 1",
    "show": true,
    "createDate": null,
    "modify_date": null,
    "ingredient": [
      {ingredient_id: 1,
       amount: 10},
      {ingredient_id: 2,
       amount: 20}
    ]
  }
]

有人可以帮我看看我在recipeIngredient课程中做错了吗?提前谢谢。

以下是我的实施:

架构: enter image description here

RecipeIngredientId.java

@Embeddable
public class RecipeIngredientId implements Serializable {
    @Column(name = "recipe_id", nullable = false)
    private int recipeId;

    @Column(name = "ingredient_id", nullable = false)
    private int ingredientId;

    public RecipeIngredientId() {}

    public RecipeIngredientId(int recipeId, int ingredientId) {
        this.recipeId = recipeId;
        this.ingredientId = ingredientId;
    }
}

RecipeIngredient.java

@Entity
@Table(name = "recipe_ingredient")
public class RecipeIngredient implements Serializable
{
    @EmbeddedId
    private RecipeIngredientId id;

    @ManyToOne
    @JoinColumn(name="ingredient_id", insertable = false, updatable = false)
    private Ingredient ingredient;
    @ManyToOne
    @JoinColumn(name = "recipe_id", insertable = false, updatable = false)
    private Recipe recipe;
    private double amount;

    public RecipeIngredient() {}

    public RecipeIngredient(Recipe recipe, Ingredient ingredient, double amount){
        this.recipe = recipe;
        this.ingredient = ingredient;
        this.amount = amount;
    }
}

Recipe.java:

@Entity
public class Recipe {
    private int id;

    @NotNull
    private String name;

    private String instruction;
    private String note;

    @NotNull
    private boolean show;

    @CreationTimestamp
    @Temporal(TemporalType.DATE)
    @Column(name = "create_date")
    private Date createDate;

    @UpdateTimestamp
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "modify_date")
    private Date modify_date;

    private Set<RecipeIngredient> recipeIngredients;

    public Recipe() {}

    public Recipe(String name, String instruction, String note, boolean show) {
        this.name = name;
        this.instruction = instruction;
        this.note = note;
        this.show = show;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getInstruction() {
        return instruction;
    }

    public void setInstruction(String instruction) {
        this.instruction = instruction;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public boolean isShow() {
        return show;
    }

    public void setShow(boolean show) {
        this.show = show;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public Date getModify_date() {
        return modify_date;
    }

    public void setModify_date(Date modify_date) {
        this.modify_date = modify_date;
    }

    @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL)
    public Set<RecipeIngredient> getIngredient() {
        return recipeIngredients;
    }

    public void setIngredient(Set<RecipeIngredient> recipeIngredients) {
        this.recipeIngredients = recipeIngredients;
    }
}

Ingredient.java

@Entity
public class Ingredient {
    private int id;

    @NotNull
    @Column(unique=true)
    private String name;

    private Set<RecipeIngredient> recipeIngredients;

    public Ingredient() {}

    public Ingredient(String name) {
        this.name = name;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @OneToMany(mappedBy = "ingredient", cascade = CascadeType.ALL)
    public Set<RecipeIngredient> getRecipeIngredients() {
        return recipeIngredients;
    }

    public void setRecipeIngredients(Set<RecipeIngredient> recipeIngredients) {
        this.recipeIngredients = recipeIngredients;
    }
}

1 个答案:

答案 0 :(得分:0)

这是&#34;派生身份&#34;的情况。 RecipeIngredient应如下所示:

@Entity
@Table(name = "recipe_ingredient")
public class RecipeIngredient implements Serializable
{
    @EmbeddedId
    private RecipeIngredientId id;

    @MapsId("ingredientId") // maps ingredientId attribute of embedded id
    @ManyToOne
    @JoinColumn(name="ingredient_id", insertable = false, updatable = false)
    private Ingredient ingredient;

    @MapsId("recipeId") // maps recipeId attribute of embedded id
    @ManyToOne
    @JoinColumn(name = "recipe_id", insertable = false, updatable = false)
    private Recipe recipe;
    private double amount;

    public RecipeIngredient() {}

    public RecipeIngredient(Recipe recipe, Ingredient ingredient, double amount){
        this.recipe = recipe;
        this.ingredient = ingredient;
        this.amount = amount;
    }
}

请注意主键构成实体复合键的两个字段上的MapsId注释。

派生身份在JPA 2.1规范2.4.1节中讨论。