我有一个这样的模型:
@Entity
public class DayMenuItem {
@Id @GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private MonetaryAmount price;
private Product product;
private String name;
@ManyToOne(targetEntity = DayMenu.class)
private DayMenu dayMenu;
...
}
有吸气剂和二传手。我有DayMenu模型,它也有id属性。
我创建了DayMenuItem类的新实例,设置了相应的dayMenu属性并将其传递给视图。在视图中,用户可以设置其他属性,如价格或名称。 我现在想通过将dayMenu属性传递给隐藏的输入字段来将dayMenu属性转发给下一个控制器。我的百万美元视图表单如下所示:
<form th:acction="@{/admin/addMenuItem}" th:object="${menuitem}" method="post">
<p>Name: </p><input type="text" th:field="*{name}"/>
<p>Price: </p><input type="text" th:field="*{price}"/>
<button>Ok</button>
<input type="hidden" th:field="${menuitem.dayMenu}" th:value="${menuitem.getDayMenu()}"/>
</form>
JPA(?)选择(正确的)DayMenu Id作为隐藏输入的值。但是当我尝试将模型重新置于控制器中时,它不再接受Id值。
我的控制器头看起来像这样:
@RequestMapping(value = "/admin/addMenuItem", method = RequestMethod.POST)
public ModelAndView addMenuItemPost(@Valid @ModelAttribute("menuitem") DayMenuItem dayMenuItem,
BindingResult bindingResultDayMenuItem,
ModelAndView modelAndView) { ...
当我看一下BindingResult时,我看到了这个错误,而dayMenu属性为null。 (1是DayMenu id)
org.springframework.validation.BeanPropertyBindingResult:1个错误 字段'dayMenu'中对象'menuitem'中的字段错误:被拒绝的值[1];代码[typeMismatch.menuitem.dayMenu,typeMismatch.dayMenu,typeMismatch.winetavern.model.menu.DayMenu,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable:codes [menuitem.dayMenu,dayMenu];参数[];默认消息[dayMenu]];默认消息[无法将类型[java.lang.String]的属性值转换为属性'dayMenu'的必需类型[winetavern.model.menu.DayMenu];嵌套异常是org.springframework.core.convert.ConversionFailedException:无法将类型[java.lang.String]转换为类型为“1”的类型[@javax.persistence.ManyToOne winetavern.model.menu.DayMenu];嵌套异常是java.lang.ClassCastException:java.lang.Long无法强制转换为org.salespointframework.core.SalespointIdentifier]
为什么JPA不再接受ID作为对象的标识符并抛出异常,尽管它曾经从对象转换为ID值?
提前致谢!
答案 0 :(得分:1)
spring无法从提供的字符串中推断出对象
试,
<input type="hidden" th:field="dayMenu" th:value="${menuitem.getDayMenu()}"/>
@ModelAttribute("menuitem")
public DayMenuItem getDayMenuItem (@RequestParam String dayMenu){
DayMenuItem item = new DayMenuItem();
DayMenu mi = new DayMenu();
mi.setId(dayMenu);
item.setDayMenu(mi);
return item ;
}
@RequestMapping(value = "/admin/addMenuItem", method = RequestMethod.POST)
public ModelAndView addMenuItemPost(@Valid @ModelAttribute("menuitem") DayMenuItem dayMenuItem,
BindingResult bindingResultDayMenuItem,
ModelAndView modelAndView){..}
答案 1 :(得分:0)
过了一段时间,我找到了最好的解决方案。我把initBinder放在我的控制器类中,看起来像这样:
@InitBinder
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(DayMenu.class, "dayMenu", new PropertyEditorSupport() {
@Override
public String getAsText() {
DayMenu dayMenu = (DayMenu) getValue();
return String.valueOf(dayMenu.getId());
}
@Override
public void setAsText(String text) {
DayMenu dayMenu = dayMenuRepository.findById(Long.parseLong(text));
setValue(dayMenu);
}
});
}
将getAsText()返回值作为隐藏输入值,并在表单输入传递给控制器时调用setAsText()方法。