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

Spring Data JPA查询@OneToMany双向映射实体报StackOverflowError如何解决

问题根因

双向关联的JPA实体CustomerEntity和AccountEntity的toString方法形成了循环调用:

  • CustomerEntity的toString逻辑中直接打印关联字段accountEntities,会触发每个AccountEntity的toString调用
  • AccountEntity的toString逻辑中又直接打印关联字段customerEntity,反过来触发CustomerEntity的toString调用
    无限循环最终导致栈内存耗尽,抛出StackOverflowError。你业务代码中的System.out.println(customers)是触发toString调用的直接诱因。
解决方案

按优先级可选以下任意方案处理:

  • 修改toString方法,打断循环调用
    重写两个实体的toString方法时,排除双向关联字段,或者仅打印关联实体的主键字段而非完整对象,示例修改如下:
    // CustomerEntity的toString修改,移除accountEntities或仅打印账户编号
    @Override
    public String toString() {
        return "CustomerEntity [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", dob=" + dob
                + ", mobileNumber=" + mobileNumber + ", emailId=" + emailId + ", address=" + address + ", createdTime="
                + createdTime + "]";
    }
    
    // AccountEntity的toString修改,移除customerEntity或仅打印关联客户id
    @Override
    public String toString() {
        return "AccountEntity [id=" + id + ", accountNumber=" + accountNumber + ", branch=" + branch + ", accountType="
                + accountType + ", balance=" + balance + ", createdTime=" + createdTime + ", customerId="
                + (customerEntity != null ? customerEntity.getId() : null) + "]";
    }
    
  • 如果使用Lombok自动生成实体方法
    在双向关联字段上添加@ToString.Exclude注解,避免Lombok自动生成的toString逻辑包含关联字段,同时建议同步给关联字段加@EqualsAndHashCode.Exclude,避免equals、hashCode方法也出现循环问题。
  • 序列化/打印场景额外处理
    若需要将实体序列化为JSON返回,可在关联字段上添加Jackson注解打断循环:在@OneToMany侧加@JsonManagedReference,@ManyToOne侧加@JsonBackReference,或者直接用@JsonIgnore忽略不需要序列化的关联字段。
补充注意事项

如果你需要在返回的CustomerDTO中包含关联账户信息,需要注意当前accountEntities的默认加载策略是懒加载,直接在事务外访问会抛出懒加载异常,建议自定义Repository查询方法,使用JOIN FETCH语句主动加载关联的accountEntities数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 08:12:01