Spring Boot Rest中OneToMany关联场景下Story类单条记录插入失败问题排查
解决OneToMany关联下保存Story时的StackOverflowError问题
从你提供的日志里,能一眼定位到问题根源:StackOverflowError是因为Book和Story的toString()方法互相引用,触发了无限递归调用。
看日志里的栈跟踪片段就能确认:
java.lang.StackOverflowError: null at in.techSoft.OTM.Entity.Book.toString(Book.java:12) at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453) at in.techSoft.OTM.Entity.Story.toString(Story.java:11) ...
这说明你的Book类toString()里包含了关联的Story列表,而Story类的toString()又包含了关联的Book对象。当你在日志中打印book或stry时,两个方法会循环调用直到栈溢出。
具体解决步骤
1. 修复实体类的toString方法
你需要修改Book和Story的toString(),彻底切断循环引用:
- Book类:不要直接打印整个
storyList,可以只打印列表长度或每个Story的ID:
// Book类的toString示例 @Override public String toString() { return "Book{" + "id=" + id + ", bookName='" + bookName + '\'' + ", storyCount=" + (storyList != null ? storyList.size() : 0) + '}'; }
- Story类:不要打印完整的
Book对象,只打印关联的Book ID即可:
// Story类的toString示例 @Override public String toString() { return "Story{" + "storyId=" + storyId + ", storyName='" + storyName + '\'' + ", bookId=" + (book != null ? book.getId() : null) + '}'; }
2. 优化Repository查询的异常处理
你的代码里bookRepository.findById(id).get()存在风险——如果传入的ID对应的Book不存在,会直接抛出NoSuchElementException,建议改成更友好的异常处理:
Book book = bookRepository.findById(id) .orElseThrow(() -> new RuntimeException("Book not found with id: " + id));
这样能明确抛出找不到Book的异常,方便后续排查问题。
3. 确认关联逻辑的正确性
你的双向关联维护是没问题的:book.addStory(stry);和stry.setBook(book);保证了关联的一致性,这部分不需要修改。
完成上述修改后,再用Postman测试保存接口,应该就能正常插入Story数据了。
内容的提问来源于stack exchange,提问作者santosh patil




