【问题标题】:Unable to Save ArrayList of Objects in MySQL - Hibernate/Spring Boot无法在 MySQL 中保存对象的 ArrayList - Hibernate/Spring Boot
【发布时间】:2021-04-09 17:23:02
【问题描述】:

我认为我在 Hibernate 中的关系映射存在一些问题。这是一个食谱保存应用程序。

最初,recipe 类有一个String ingredients 字段,其中存储了所有成分。我们意识到这对于在配方中存储成分列表没有意义,因此我正在将其重构为我创建的新类型列表Ingredient:List<Ingredient> ingredients。配料表字段由前端的JS动态创建,在POST请求中提交时,转化为新配料的ArrayList,然后添加到Recipe模型中。

每当它到达将其保存到数据库中的行时,我都会收到此错误:

Field 'ingredients' doesn't have a default value,它告诉我该字段为空。但是,当我使用调试工具时,它显示 newRecipe.ingredients 不为空,它实际上是一个从前端数据创建的 ArrayList。

成分类如下所示:

@Entity
public class Ingredient extends AbstractEntity{

    @ManyToOne(targetEntity = Recipe.class,
            fetch = FetchType.LAZY,
            cascade = {CascadeType.MERGE, CascadeType.REMOVE})
    @NotNull(message = "Please include ingredients")
    private Recipe recipe;

    @Id
    @GeneratedValue
    private int id;

    private String ingredient;

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

    public String getIngredient() {
        return ingredient;
    }

    public void setIngredient(String ingredient) {
        this.ingredient = ingredient;
    }

}

配方类在这里:

@Entity
public class Recipe extends AbstractEntity {

   private String name;

   @OneToMany(mappedBy = "recipe")
   @NotNull(message = "Ingredients required")
   private List<Ingredient> ingredients = new ArrayList<Ingredient>();

   private String directions;

   @OneToMany(mappedBy = "recipe")
   private List<Instruction> instructions = new ArrayList<Instruction>();

   @NotNull(message = "Category required")
   private Category category;

   private Tag tag;

   private String img;

   @OneToMany(mappedBy = "recipe", cascade = {CascadeType.MERGE, CascadeType.REMOVE})
   @NotNull(message = "User is required")
   private List<UserRecipe> users = new ArrayList<>();

   public Recipe() {
   }

   public String getName() {
      return name;
   }

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


   public Category getCategory() {
      return category;
   }

   public void setCategory(Category category) {
      this.category = category;
   }

   public List<UserRecipe> getUsers() {
      return users;
   }

   public void setUsers(List<UserRecipe> users) {
      this.users = users;
   }

   public String getImg() {
      return img;
   }

   public void setImg(String img) {
      this.img = img;
   }


   public List<Ingredient> getIngredients() {
      return ingredients;
   }

   public void setIngredients(List<Ingredient> ingredients) {
      this.ingredients = ingredients;
   }

   public String getDirections() {
      return directions;
   }

   public void setDirections(String directions) {
      this.directions = directions;
   }

   public Tag getTag() {
      return tag;
   }

   public void setTag(Tag tag) {
      this.tag = tag;
   }

   public List<Instruction> getInstructions() {
      return instructions;
   }

   public void setInstructions(List<Instruction> instructions) {
      this.instructions = instructions;
   }
}

RecipeController 在这里:

@PostMapping("create")
   public String createRecipe(HttpServletRequest request, @ModelAttribute Recipe newRecipe,
                              @ModelAttribute @Valid String newCategory,
                              Errors errors, Model model, RedirectAttributes redirectAttrs) {

      if (errors.hasErrors()) {
         model.addAttribute("title", "Create Recipe");
         return "recipes/create";
      }

      String[] ingredients = request.getParameterValues("ingredient");

      List<Ingredient> ingredientsList = new ArrayList<Ingredient>();

      for (int i = 0; i < ingredients.length; i++) {
         Ingredient newIngredient = new Ingredient(ingredients[i]);
         ingredientsList.add(newIngredient);
      }
      newRecipe.setIngredients(ingredientsList);
      
      // THIS PRINTS AN ARRAY OF THE NUMBER OF INGREDIENTS ADDED
      System.out.println(ingredientsList.toString());

      // HERE IS WHERE MY ERROR HAPPENS
      Recipe recipe = recipeRepository.save(newRecipe);
      redirectAttrs.addAttribute("recipeId", recipe.getId());

      return "redirect:/recipes/display";
   }

我的想法是,我在某种程度上没有将成分列表正确映射到食谱,但我无法弄清楚这一点,经过 3 天的谷歌搜索和故障排除后,我来到了这里。任何帮助将不胜感激。提前致谢!

【问题讨论】:

    标签: java mysql spring-boot hibernate arraylist


    【解决方案1】:

    这可能是您的数据库中的架构问题。您是手动创建架构还是使用 auto-ddl?如果您手动创建它,则可能在成分表中缺少 recipe_id 列。如果此类连接列具有不同的名称,则必须在成分类上使用 @JoinColumn 覆盖它,如下所示:

    @ManyToOne(targetEntity = Recipe.class,
                fetch = FetchType.LAZY,
                cascade = {CascadeType.MERGE, CascadeType.REMOVE})
        @NotNull(message = "Please include ingredients")
        @JoinColumn("the_recipe_id") // **** Here you put the join column name you specified **** //
        private Recipe recipe;
    
    

    编辑:另外,你能发布你的 AbstractEntity 类吗?该问题也可能与 Recipe 类中缺少键有关。

    【讨论】:

    • 谢谢,圣地亚哥。这绝对是 DB 的问题 - 不幸的是,我没有更改 ingredient 的数据类型。创建一个新的数据库解决了这个问题。
    • 很高兴听到这个消息!干杯!
    【解决方案2】:

    我是个白痴。数据库中的数据类型设置不正确。创建一个新的数据库解决了它。

    【讨论】:

      猜你喜欢
      • 2021-01-28
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 2020-12-31
      • 2017-03-05
      • 2023-01-12
      • 1970-01-01
      • 2021-03-24
      相关资源
      最近更新 更多