Spring Boot中使用JPA批量插入多行数据遇问题求助
问题解决方案
问题根源
- 表单提交时,所有选中的
code因同名name="code"被Spring MVC拼接为单个字符串,绑定到单个CourseTwo的code字段,导致所有代码存入同一行。 - 尝试的批量代码错误:用单个
CourseTwo对象初始化ArrayList,违反集合构造参数要求,触发No primary or single unique constructor found for interface java.util.List异常。
1. 修正表单提交逻辑
移除单个CourseTwo绑定,改为提交选中的CourseOne ID列表:
<form th:action="@{/saveCourseTwo}" method="post"> <div class="overflow-scroll" style="border: 2px dashed; height:300px; width:800px"> <div class="table-responsive"> <table class="table table-sm table-striped table-hover" style="width: 100%"> <thead class="green white-text"> <tr> <th>Select</th> <th>Code</th> <th>Title</th> <th>Units</th> </tr> </thead> <tbody> <tr th:each="course : ${listCourseOne}"> <td> <input type="checkbox" class="form-check-input" name="selectedCourseIds" th:value="${course.courseOneId}" /> </td> <td th:text="${course.code}"></td> <td th:text="${course.title}"></td> <td th:text="${course.units}"></td> </tr> </tbody> </table> </div> </div> <button type="submit" class="btn btn-success">Save</button> </form>
- 去掉
th:object="${courseTwo}",无需绑定单个对象 - 复选框
name设为selectedCourseIds,传递选中的CourseOneID列表
2. 新增CourseOne仓库(若未存在)
用于查询选中的课程信息:
public interface CourseOneRepository extends CrudRepository<CourseOne, Long> { }
3. 修改服务层批量保存逻辑
接收ID列表,批量创建CourseTwo实例并保存:
@Service public class CourseTwoService { private final CourseTwoRepository courseTwoRepo; private final CourseOneRepository courseOneRepo; // 构造注入 public CourseTwoService(CourseTwoRepository courseTwoRepo, CourseOneRepository courseOneRepo) { this.courseTwoRepo = courseTwoRepo; this.courseOneRepo = courseOneRepo; } public List<CourseTwo> saveCourseTwo(List<Long> selectedCourseIds) { List<CourseTwo> courseTwoList = new ArrayList<>(); for (Long courseOneId : selectedCourseIds) { // 查询对应CourseOne实例 CourseOne courseOne = courseOneRepo.findById(courseOneId) .orElseThrow(() -> new IllegalArgumentException("CourseOne not found with id: " + courseOneId)); // 创建CourseTwo并赋值 CourseTwo courseTwo = new CourseTwo(); courseTwo.setCode(courseOne.getCode()); courseTwo.setCourseOne(courseOne); courseTwoList.add(courseTwo); } // 批量插入 return (List<CourseTwo>) courseTwoRepo.saveAll(courseTwoList); } }
4. 编写控制器处理请求
接收表单提交的ID列表,调用服务层:
@Controller public class CourseController { private final CourseTwoService courseTwoService; private final CourseOneRepository courseOneRepo; public CourseController(CourseTwoService courseTwoService, CourseOneRepository courseOneRepo) { this.courseTwoService = courseTwoService; this.courseOneRepo = courseOneRepo; } // 显示课程选择表单 @GetMapping("/selectCourses") public String showSelectForm(Model model) { model.addAttribute("listCourseOne", courseOneRepo.findAll()); return "course-select"; // 替换为你的视图名称 } // 处理批量保存请求 @PostMapping("/saveCourseTwo") public String saveCourseTwo(@RequestParam("selectedCourseIds") List<Long> selectedCourseIds) { courseTwoService.saveCourseTwo(selectedCourseIds); return "redirect:/success"; // 替换为保存成功后的跳转页面 } }
5. 实体关系优化(可选)
当前一对一关系限制每个CourseOne只能关联一个CourseTwo,若业务允许重复插入同一课程,需改为一对多:
- 修改
CourseOne:
@OneToMany(mappedBy = "courseOne", cascade = CascadeType.ALL) private List<CourseTwo> courseTwoList = new ArrayList<>();
- 修改
CourseTwo:
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinColumn(name = "course_one_id") private CourseOne courseOne;
内容的提问来源于stack exchange,提问作者Done-Q
相关产品推荐
相关产品推荐

