所以我有一个JPA实体Expense
,它有一些属性,比如id,版本,用户实体被映射为@ManyToOne
。
当用户进入详细信息页面时,控制器将他发送到那里,通过以下方式将相关费用对象添加到模型中:
@RequestMapping(value = "/details/{id}", method = RequestMethod.GET)
public String details(@PathVariable("id") Long id, Model model){
Expense expense;
try {
expense = expenseService.findExpenseById(id);
logger.info("sending to details page, id is " + expense.getId());
} catch (ExpenseException e) {
//TODO: optionally add info message
model.addAttribute("error", messageSource.getMessage("error_already_removed", null, sessionLocaleResolver.resolveLocale(httpServletRequest)));
return "redirect:/expense/overview";
}
model.addAttribute("expense", expense);
return "details";
}
费用对象显然仍然完好无损,因为我刚刚从数据库中检索它,所有属性都被正确填充。
但是,当用户在视图中编辑属性并保存时,他会碰到以下控制器方法:
@RequestMapping(value = "/edit", method = RequestMethod.POST)
public String edit(@ModelAttribute("expense") @Valid Expense expense, BindingResult bindingResult){...}
在几个日志之后,我发现费用对象只包含详细信息页面上表单中存在的属性(显然不包括id和版本)。因此,当程序继续合并费用时,hibernate会在数据库中插入新的费用,因为id为null。
我尝试的事情:
在uri中添加id,使用此ID检索旧费用并在更新的费用对象上复制不可编辑的属性。
将不可编辑的属性添加为表单中的隐藏输入字段(但这给了我转换错误,因为Spring无法将User实体的String表示形式转换为User实体对象本身)< / p>
然而,这两种方法对我来说似乎并不合适,这使我相信必须有一种更方便的推荐方法将jpa实体传递给模型并在以后的方法中检索它们的属性。