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

使用Spring JPA的findAllByPropertyTitleContaining方法遇StackOverflowError

Spring Boot调用JPA findAllByPropertyTitleContaining触发StackOverflowError问题解决

问题描述

基于Spring Boot开发项目,使用Thymeleaf作为模板引擎。调用Spring JPA的findAllByPropertyTitleContaining方法时,触发了StackOverflowError错误。

相关代码

Property实体类

package com.example.estateagencyspring.models;

import lombok.Data;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Data
public class Property {

    @Id
    private String id;
    private String propertyTitle;
    private String propertyDescription;
    private String location;
    private String type;
    private String status;
    private String area;
    private String beds;
    private String baths;
    private String garage;
    private String defaultPicture;
    private String price;
    @Lob
    private String googleSrc;


    @OneToMany(mappedBy="property")
    private List<Picture> pictures = new ArrayList<>();

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
            name = "property_amenity",
            joinColumns = @JoinColumn(name = "property_id"),
            inverseJoinColumns = @JoinColumn(name = "amenity_id")
    )
    private List<Amenity> amenities = new ArrayList<>();
}

Amenity实体类(与Property为ManyToMany关联)

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.util.ArrayList;
import java.util.List;

@Entity
@Data
public class Amenity {

    @Id
    private String id;
    private String name;

    @ManyToMany(mappedBy = "amenities", fetch = FetchType.LAZY)
    private List<Property> properties = new ArrayList<>();
}

PropertyRepository接口

public interface PropertyRepository extends JpaRepository<Property, String> {

    Optional<Property> findByPropertyTitle(String title);

    List<Property> findAllByPropertyTitleContaining(String title);

}

PropertyService相关方法

...
public List<Property> searchByTitle(String title){
        System.out.println(propertyRepository.findAllByPropertyTitleContaining(title));
        return propertyRepository.findAllByPropertyTitleContaining(title);
    }

原因分析

StackOverflowError的核心原因是双向ManyToMany关联引发的循环引用。你使用了Lombok的@Data注解,该注解会自动生成toString()、equals()、hashCode()方法。当执行System.out.println打印查询结果时,Property的toString()会遍历其amenities集合;而每个Amenity的toString()又会遍历自身的properties集合,如此往复形成无限循环,最终导致栈内存溢出。

解决方法

方法一:用Lombok注解排除循环字段

在双向关联的其中一方字段上添加@ToString.Exclude,避免toString()方法包含该关联集合:

  • 示例:修改Property类的amenities字段
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(
        name = "property_amenity",
        joinColumns = @JoinColumn(name = "property_id"),
        inverseJoinColumns = @JoinColumn(name = "amenity_id")
)
@ToString.Exclude
private List<Amenity> amenities = new ArrayList<>();
  • 或者修改Amenity类的properties字段
@ManyToMany(mappedBy = "amenities", fetch = FetchType.LAZY)
@ToString.Exclude
private List<Property> properties = new ArrayList<>();

方法二:手动重写toString()方法

去掉@Data中的自动生成逻辑,手动编写toString()方法,只包含基本属性,不涉及双向关联的集合:
示例:在Property类中重写

@Override
public String toString() {
    return "Property{" +
            "id='" + id + '\'' +
            ", propertyTitle='" + propertyTitle + '\'' +
            ", propertyDescription='" + propertyDescription + '\'' +
            ", location='" + location + '\'' +
            ", type='" + type + '\'' +
            ", status='" + status + '\'' +
            ", area='" + area + '\'' +
            ", beds='" + beds + '\'' +
            ", baths='" + baths + '\'' +
            ", garage='" + garage + '\'' +
            ", defaultPicture='" + defaultPicture + '\'' +
            ", price='" + price + '\'' +
            ", googleSrc='" + googleSrc + '\'' +
            '}';
}

方法三:替换@Data为更细粒度的Lombok注解

用@Getter、@Setter、@RequiredArgsConstructor等注解替代@Data,避免自动生成包含关联集合的toString()、equals()等方法:

@Entity
@Getter
@Setter
@RequiredArgsConstructor
public class Property {
    // 实体属性及关联字段不变
}

内容的提问来源于stack exchange,提问作者Oth Mane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 20:39:06