繁体   English   中英

更新多个实体的Spring Data JPA问题

[英]Spring Data JPA problem with updating multiple Entities

我有2个实体类,即"Menu" ,其中只有一个字段称为"name" ,第二个实体- "Ingredients"具有2个字段,即"ingredientName""ingredientDescription" 数据库结构

我正在创建一个简单的CRUD Web应用程序,但是update方法而不是Entity,而是在DB中插入了新值。 我检查了一下,当用户单击指定菜单上的更新时,将预先定义第一个实体的ID及其成分ID 我是Spring Boot和thymeleaf的新手,当您拥有多个实体时,真的不知道如何使用JPA。

菜单实体:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;

@Column(name = "name")
private String name;

// Mapping To second table
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinTable(name = "menu_ingredient",
        joinColumns = @JoinColumn(name = "menu_id"),
        inverseJoinColumns = @JoinColumn(name = "ingredient_id"))
private List<Ingredients> ingredient = new ArrayList<>();

//Getters/Setters/Constructors/ToString

成分实体:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@Column(name = "ingredient")
private String ingredientName;

@Column(name = "description")
private String ingredientDescription;

//Getters/Setters/Constructors/ToString

控制器(仅更新方法):

@GetMapping("/edit/{id}")
public String edit(@PathVariable(name = "id")String id, Model model){
    Optional<Menu> menu = menuRepository.findById(id);

    List<Ingredients> ingredients = menu.get().getIngredient();

    for (Ingredients ing : ingredients){
        System.out.println(ing);
    }

    model.addAttribute("ingredients", ingredients);
    model.addAttribute("newMenu",menu);


    return "edit-page";
}

@PostMapping("/postEditMenu")
public String postEdit(@ModelAttribute("newMenu")Menu menu){



    menuRepository.save(menu);

    return "redirect:/recipeList";
}

edit-page.html:

    <form action = "#" th:action="@{/postEditMenu}" th:object="${newMenu}" method="post">
        <p>Menu Name: <br><input type="text" th:field="*{name}"></p>
        <div id="wrapper" th:each="ing: ${ingredients}">
            <label for="ingredientName"></label>
            <p>Ingredient Name: <br><input th:value="${ing.ingredientName}" id="ingredientName" type="text" name="ingName"></p>

            <label for="ingredientDescription"></label>
            <p>Ingredient Description:</p> <textarea id="ingredientDescription" type="text" th:text="${ing.ingredientDescription}" name="ingDesc"></textarea>
        </div>
        <br>

        <input type="button" id="more_fields" onclick="add_fields();" value="Add More" />
        <br>

        <input type="submit" th:value="Submit">

    </form>

FIX我实际上是在以下答案的帮助下找到答案的。 这是代码:

@PostMapping("/postEditMenu")
public String postEdit(@ModelAttribute("newMenu")Menu menu,
                       @RequestParam String ingName,
                       @RequestParam String ingDesc){

    String[] ingNameSplit = ingName.split(",");
    String[] ingDescSplit = ingDesc.split(",");

    Menu menuToUpdate = menuRepository.getOne(menu.getId());


    List<Ingredients> newIngredientList = menuToUpdate.getIngredient();
    newIngredientList.clear();

    for(int a = 0, b = 0; a<ingNameSplit.length; b++, a++){
        newIngredientList.add(new Ingredients(ingNameSplit[a], ingDescSplit[b]));
    }
    menuToUpdate.setIngredient(newIngredientList);

    menuRepository.save(menuToUpdate);

    return "redirect:/recipeList";
}

因此,首先,我向所需的每个项目中添加了隐藏的“ id”字段,如下所示:

<input type="text" th:field = "*{id}" hidden>

<input type="text" th:value = "${ing.id}" hidden>

然后,在postEditMenu方法中,我添加了@RequestParam String ingName,@RequestParam String ingDesc以从百里香@RequestParam String ingDesc中获取新项目的输入,然后我将该字符串拆分并使用String[] ingNameSplit = ingName.split(",")将其添加到String []数组中String[] ingNameSplit = ingName.split(",")因为输入将是一个用大逗号分隔的String而不是array []。 然后我得到用户想要更新的Menu menuToUpdate = menuRepository.getOne(menu.getId()); menu.getId()不为null,因为我在百里香中设置了隐藏的“ id”字段。 然后,我得到此菜单的List<Ingredients> newIngredientList = menuToUpdate.getIngredient(); 因为该列表将已经充满现有成分,所以我清除了该列表并添加了新的成分,用户将用-

for(int a = 0, b = 0; a<ingNameSplit.length; b++, a++){
            newIngredientList.add(new Ingredients(ingNameSplit[a], ingDescSplit[b]));
        }

之后,我设置此newIngredientsList并将菜单本身保存到newIngredientsList

menuToUpdate.setIngredient(newIngredientList);

menuRepository.save(menuToUpdate);

谢谢大家的帮助:)

首先,您需要使用getOne通过id从数据库中获取Menu实体,然后可以对其进行更新。

postEdit方法中编辑代码,如下所示:

提取菜单实体:

Menu menuToUpdate = menuRepository.getOne(menu.getId());

更新属性:

menuToUpdate.setName(menu.getName());

保存实体:

menuRepository.save(menuToUpdate); 

这一点:

@PostMapping("/postEditMenu")
public String postEdit(@ModelAttribute("newMenu")Menu menu){


menuRepository.save(menu);

return "redirect:/recipeList";
}

您从edit-page.html接收菜单,它没有ID,这就是为什么它总是在数据库中创建新记录的原因。 要编辑所需菜单,您需要先获得其ID。 您可以创建端点来获取菜单列表,并使用html站点中每个菜单旁边的编辑按钮来显示它们。 然后,如果用户单击“编辑”按钮,会将其重定向到您的编辑表单,但是这次您可以传递菜单的ID。

添加一个隐藏的ID字段来保存菜单的ID,并为每种成分添加一个隐藏的ID字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM