gpt4 book ai didi

java - Hibernate Spring - @OneToMany - 外键未存储在数据库中

转载 作者:行者123 更新时间:2023-11-30 08:59:35 25 4
gpt4 key购买 nike

要求 - 对于食谱应用程序,用户可以输入食谱名称和成分。用户可以在 JSP 页面上输入一种以上的食谱成分。

数据库模型:创建了 2 个表。 (食谱可以有不止一种成分)

Recipe - 
recipe_id (primary key)
name

Ingredient
ingredient_id (primary key)
recipe_id (foreign key to recipe(recipe_id))
quantity
ingredient

问题 - 对于这种情况,@OneToMany(如下所示)用于 Hibernate 映射,但当用户保存表单时,外键(即 recipe_id)未存储在成分表。假设用户输入如下:

Recipe -  Sandwich
Ingredient - 250g(as quantity) Salt (as ingredient)

保存后以下内容被保存(即配方表中没有值)

**Recipe**
recipe_id - 1
name - Sandwich

**Ingredient**
ingredient_id - 50
recipe_id - NULL
quantity - 250g
ingredient - Salt

保存表单时没有错误。

当用户保存数据时,Hibernate 将以下内容保存在日志中:

Hibernate: select seq_recipe.nextval from dual
Hibernate: select seq_ingredient.nextval from dual
Hibernate: insert into RECIPE (NAME, RECIPE_ID) values (?, ?)
Hibernate: insert into ingredient (COMMENTS, INGREDIENT, RECIPE_ID, INGREDIENT_ID) values (?, ?, ?, ?)

Oracle 表

create table ingredient(ingredient_id number(4) primary key,
quantity varchar2(20),
ingredient varchar2(40),
recipe_id number(4),
constraint recipe_fk foreign key (recipe_id)
references recipe(recipe_id));

create table recipe(id number primary key,
name varchar2(25) unique,
ingredient_id number(4),
constraint ingredient_fk foreign key(ingredient_id)
references ingredient(ingredient_id));

成分和配方 POJO

@Entity
@Table(name = "ingredient", uniqueConstraints={
@UniqueConstraint(columnNames="INGREDIENT_ID")
})
public class Ingredient implements Serializable {
private static final long serialVersionUID = -2489479702169761646L;

@Id
@Column(name = "INGREDIENT_ID", unique=true, nullable=false)
@SequenceGenerator(name="seq_ingredient", sequenceName="seq_ingredient")
@GeneratedValue(strategy=GenerationType.AUTO, generator="seq_ingredient")
private Integer ingredientId;

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

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

@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="RECIPE_ID", nullable=false)
private Recipe recipe;

//getter and setters



@Entity
@Table(name = "recipe")
public class Recipe implements Serializable {
private static final long serialVersionUID = 4398676897855994030L;

@Id
@Column(name = "id")
private Integer id;

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

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="recipe")
private List<Ingredient> ingredients;

//getters and setter
}

当用户保存数据时,将映射/add url 并处理 POST 方法的 MVC

@RequestMapping("/add")
public String newRecipe(Model model) {
Recipe recipe = new Recipe();
recipe.setIngredients(new AutoPopulatingList<Ingredient>(Ingredient.class));

model.addAttribute("recipe", recipe);
return "recipes/new";
}

@RequestMapping(value = "add", method = RequestMethod.POST)
public String addRecipe(@Valid Recipe recipe, BindingResult result,
Model model) {
if (result.hasErrors()) {
return "recipes/new";
}
recipeServices.addRecipe(recipe);
return "redirect:/recipe/" + recipe.getId();
}

**DAO 保存 Recipe 对象 **

public class RecipeDaoImpl implements RecipeDao {
public void addRecipe(Recipe recipe) {
getSession().save(recipe);
}
}

JSP代码

<html>
<script type="text/javascript">
<!--
function addRow(tableID) {

<!-- Code delete to improve readability. Dynamically add row -->
}
-->
</script>
</head>
<body>
<s:url value="/recipe/add" var="recipe_new" />

<sf:form modelAttribute="recipe" action="${recipe_new}" method="POST">
<table>
<tr>
<th>Recipe Name:</th>
<td><sf:input path="name" id="recipeName" /> <br />
<sf:errors path="name" cssClass="error" /></td>
</tr>
<tr>
<td>
<h3>Ingredients</h3> <INPUT type="button" value="+"
onclick="addRow('dataTable')" /> <INPUT type="button" value="-"
onclick="deleteRow('dataTable')" />
<table id="dataTable" width="350px" border="1">
<tr>
<th></th>
<th>Quantity</th>
<th>Ingredient</th>
</tr>
<tr>
<td><input type="checkbox" name="chk" /></td>
<td><sf:input type="text" path="ingredients[0].quantity"
title="Quantity" placeholder="Quantity" /></td>
<td><sf:input type="text" path="ingredients[0].ingredient"
title="Ingredient" placeholder="Ingredient" /></td>
</tr>
</table>
</td>
</tr>
</table>
</sf:form>
</body>
</html>

谦虚的请求帮助我,因为我过去 2 天一直在尝试解决这个问题,但无法理解为什么外键没有存储在数据库中。

最佳答案

ma​​ppedBy 通常用于双向关系,以节省更新/插入的额外查询。

基本上是父端上的OneToMany子端上的ManyToOne

在您的情况下,mappedBy 意味着 Parent 不负责保存对 Child 的引用。

因此请尝试在您的案例中使用 @JoinColumn

关于java - Hibernate Spring - @OneToMany - 外键未存储在数据库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27162634/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com