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

Thymeleaf表单实现部分表更新及@OneToMany持久化验证问题

问题2:验证失败后UserDetails变为null的解决方法

无需额外手动查询,只需在验证失败时恢复关联的userDetailsById集合即可。

原因

Spring MVC绑定表单数据时,仅会填充表单中存在的字段,userDetailsById未在表单中声明,因此提交后的User对象中该集合为null;而初始加载的User是从数据库查询的完整对象,包含关联数据。

解决方案

采用问题1中的方案,验证失败时使用从数据库加载的原始User对象,该对象自带关联的userDetailsById集合,页面即可正常遍历显示。

额外优化:将User实体中的Collection<UserDetails>改为List<UserDetails>并初始化空集合,避免null指针:

@OneToMany(mappedBy = "userByUser")
private List<UserDetails> userDetailsById = new ArrayList<>();

问题3:传递UserDetails的comment并持久化

针对新增UserDetails记录的场景,建议通过普通请求参数接收comment,在Controller中创建UserDetails对象并关联到User后单独保存。

步骤1:修改表单

将原UserDetails输入框改为普通参数,无需绑定到User对象:

<div class="row">
    <div class="col">
        <div class="mt-3">
            <label class="form-label" for="userDetail">User Details</label>
            <input class="form-control" id="userDetail" type="text" name="comment">
        </div>
    </div>
</div>

步骤2:修改Controller方法

接收comment参数,非空则创建并保存UserDetails:

@PostMapping("/save")
public String saveUser(@Valid User submittedUser, BindingResult result, 
                       @RequestParam(value = "comment", required = false) String comment,
                       Model model) {
    if (result.hasErrors()) {
        User originalUser = userRepository.findById(submittedUser.getId()).orElse(submittedUser);
        originalUser.setAge(submittedUser.getAge());
        originalUser.setBirthplace(submittedUser.getBirthplace());
        model.addAttribute("user", originalUser);
        return "user";
    }
    // 保存User
    User savedUser = userRepository.save(submittedUser);
    // 新增评论
    if (comment != null && !comment.isEmpty()) {
        UserDetails userDetails = new UserDetails();
        userDetails.setUser(savedUser.getId());
        userDetails.setComments(comment);
        userDetailsRepository.save(userDetails);
    }
    return "redirect:/all";
}

可选规范方案:使用DTO

若需对UserDetails字段做验证,可创建包含User和新comment的DTO,统一管理验证规则:

@Data
public class UserUpdateDTO {
    @Valid
    private User user;
    @NotEmpty(message = "Comment cannot be empty")
    private String newComment;
}

后续表单绑定到DTO,Controller接收DTO并处理即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 13:06:17