You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot Web整合JPA、JSP+JSTL更新表单@Id类型转换错误求助

问题根本原因

错误的核心是控制器方法的参数顺序错误:Spring MVC要求BindingResult参数必须紧挨着它要校验的@ModelAttribute参数,中间不能插入其他参数。你当前的代码里Model参数插在了Quote实体和BindingResult中间,导致Spring参数绑定错位:本来要绑定到quote字段的文本内容,被误当成了Quote实体的id值做类型转换,所以抛出NumberFormatException,请求直接被拦截,无法进入控制器方法。

修复步骤

1. 调整控制器参数顺序

把QuoteController里的方法参数调整为BindingResult紧跟@ModelAttribute,修正后的代码如下:

@RequestMapping(value = "/update",method = RequestMethod.POST)
public String updateQuote(@ModelAttribute("quote") Quote quote, 
                          BindingResult bindingResult, 
                          Model model) {
    LOGGER.info("/update POST request received,  quote :: " + quote);

    if (bindingResult.hasErrors()) {
        LOGGER.error("/update POST request has errors :: " + bindingResult.getAllErrors());
        model.addAttribute("error", bindingResult.getAllErrors());
        return "qms/edit";
    }

    quoteService.updateQuote(quote);
    return "qms/list";
}

调整后参数绑定会恢复正常,隐藏域的id值会正确绑定到Quote实体的id字段,不会再出现类型转换错误。

2. DTO方案的问题解决

如果你要使用DTO做参数接收,不需要移除id字段,保留id字段即可:

  • 编辑页的隐藏域正常传递id值到DTO的id属性
  • 转换实体的时候,先通过DTO的id从数据库查询出原有实体,再把DTO的非id属性拷贝到查询到的实体对象上,再调用save方法,此时JPA会识别到实体有id,执行更新操作而非新增,示例逻辑:
// service层更新逻辑
public void updateQuote(QuoteDTO dto) {
    Quote existingQuote = quoteRepository.findById(dto.getId())
        .orElseThrow(() -> new RuntimeException("对应记录不存在"));
    // 拷贝属性,忽略id字段避免被覆盖
    BeanUtils.copyProperties(dto, existingQuote, "id");
    quoteRepository.save(existingQuote);
}

内容的提问来源于stack exchange,提问作者itsraghz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 06:27:03