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

查询数据库Wishlist对象时触发StackOverflowError的解决求助

问题:Spring Boot+JPA查询心愿单商品时触发StackOverflowError

在Spring Boot+JPA项目中,通过商品ID检查商品是否存在于心愿单时,调用仓库查询方法触发了StackOverflowError,相关代码及报错信息如下:

实体类代码

@Entity
@Data
@Table(name = "wishlist")
public class Wishlist {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @OneToOne(targetEntity = Customer.class, fetch = FetchType.EAGER)
    @JoinColumn(nullable = false,name = "customer_id")
    private Customer customer;

    @Column(name = "created_date")
    private Date createdDate;

    @ManyToOne
    @JoinColumn(name = "product_id")
    private Products product;

    public Wishlist(Customer customer, Products product) {
        this.customer = customer;
        this.createdDate = new Date();
        this.product = product;
    }
    
    public Wishlist() {
        
    }
}

仓库接口代码

public interface WishlistRepository extends JpaRepository<Wishlist, Integer> {
    List<Wishlist> findAllByCustomerIdOrderByCreatedDateDesc(Integer customerId);
    Optional<Wishlist> findByProductId(Integer productId);
}

服务层代码

@Service
@Transactional
public class WishlistServiceImpl implements WishlistService{

    @Autowired
    WishlistRepository wishlistRepo;

    @Override
    public void createWishlist(Wishlist wishlist,Integer productId) throws ProductNotExistsException {
        Optional<Wishlist> optionalProduct = wishlistRepo.findByProductId(productId);
        System.out.println(optionalProduct);
    }
}

报错信息

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause

java.lang.StackOverflowError: null
    at java.base/java.lang.AbstractStringBuilder.putStringAt(AbstractStringBuilder.java:1720) ~[na:na]
    at java.base/java.lang.AbstractStringBuilder.putStringAt(AbstractStringBuilder.java:1724) ~[na:na]
    at java.base/java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:583) ~[na:na]
    at java.base/java.lang.StringBuilder.append(StringBuilder.java:175) ~[na:na]
    at java.base/java.lang.StringBuilder.append(StringBuilder.java:87) ~[na:na]
    at java.base/java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:112) ~[na:na]
    at java.base/java.lang.StringBuilder.<init>(StringBuilder.java:127) ~[na:na]
    at com.ecommerce.entity.Customer.toString(Customer.java:29) ~[classes/:na]

问题原因及解决方法

原因

报错栈显示问题出在Customer类的toString方法,结合代码中使用了Lombok的@Data注解,核心原因是实体类之间的双向引用导致toString方法递归调用:

  • Wishlist类的@Data注解会自动生成包含customer属性的toString方法;
  • Customer类大概率也用了@Data或自定义了包含wishlist(或关联心愿单集合)的toString方法;
  • 执行System.out.println(optionalProduct)时,会触发Wishlist的toString,进而调用Customer的toString,而Customer的toString又会反向调用Wishlist的toString,无限递归最终导致栈溢出。

解决方法

  1. 修改Lombok注解,排除双向引用属性
    将Wishlist类的@Data替换为@Getter+@Setter+@ToString(exclude = "customer"),避免toString方法包含会触发循环的customer属性;同时检查Customer类,如果它关联了Wishlist,也要在其toString中排除对应属性,比如@ToString(exclude = "wishlist")。

    修改后的Wishlist示例:

    @Entity
    @Getter
    @Setter
    @ToString(exclude = "customer")
    @Table(name = "wishlist")
    public class Wishlist {
        // 原有属性和方法保持不变
    }
    
  2. 避免直接打印整个实体对象
    如果只需要判断商品是否存在,直接打印判断结果即可,无需输出整个实体:

    System.out.println("商品是否在心愿单中:" + optionalProduct.isPresent());
    // 或仅打印关键属性
    optionalProduct.ifPresent(w -> System.out.println("心愿单记录ID:" + w.getId()));
    
  3. 清理不必要的双向关联
    检查Customer类中是否存在@OneToOne(mappedBy = "customer")的Wishlist属性,如果业务上不需要双向关联,直接删除该属性,从根源避免循环引用问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 04:25:40