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

使用Hibernate的@ManyToOne与@OneToMany注解时触发StackOverflowError异常

使用Hibernate的@ManyToOne与@OneToMany注解时触发StackOverflowError异常

兄弟,看你的异常栈就能一眼定位问题——这是实体类的toString方法触发了无限循环调用!

你仔细看异常日志,反复出现Ticket.toString()和Material.toString()互相调用的栈帧:Ticket的toString会遍历materials列表,调用每个Material的toString;而Material的toString又会引用ticket对象,再次触发Ticket的toString。这样无限循环下去,直接把调用栈撑爆,就抛出StackOverflowError了。

解决方法很简单,修改实体类的toString方法即可:

核心思路是避免在toString中直接引用双向关联的完整对象,改用ID或者简单属性代替,打断循环链:

  1. 修改Ticket类的toString:不要直接打印materials列表,改成打印材料数量或者ID列表
@Override
public String toString() {
    return "Ticket{" +
            "id=" + getId() +
            ", name='" + getName() + '\'' +
            // 只打印材料数量,避免调用Material的toString
            ", materialsCount=" + (materials != null ? materials.size() : 0) +
            '}';
}
  1. 修改Material类的toString:不要直接打印ticket对象,改成打印关联Ticket的ID
@Override
public String toString() {
    return "Material{" +
            "id=" + getId() +
            ", name='" + getName() + '\'' +
            // 只打印关联Ticket的ID,避免调用Ticket的toString
            ", ticketId=" + (ticket != null ? ticket.getId() : null) +
            '}';
}

额外说明:

你的查询写法(@EntityGraph或者JOIN FETCH)本身是没问题的,StackOverflow不是查询加载数据导致的,是加载后触发toString循环调用才出的问题。如果是IDE自动生成的toString(比如IDEA默认生成),记得手动去掉双向关联的字段,别图省事全选所有字段。

备注:内容来源于stack exchange,提问作者VadiMayer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 16:03:11