StackOverflowError Springboot 一对多双向映射

StackOverflowError Springboot OneToMany BiDirectional Mapping

我目前正在编写一个项目,这需要我在两个实体之间进行映射:一个帐户和一个成员。一个账户可以有多个会员,而一个会员只能有一个账户。
在我完成双向编码后,一切正常,我得到了我想要的响应,这只是成员。

问题从这里开始:
我开始编写自己的“食谱”。 Recipe 以 ManyToOne 关系连接到“house”,然后与“account”建立 1:1 关系。实现这个之后,我发现了一个以前不存在的 Whosebug。 (帐户和会员之间的那个)

下面是数据库中所述结构的图像。食谱 -> 房屋 -> 账户。 (存在顶部带有蓝色十字的关系和表格,但并未真正连接)

我的实体如下所示:

package com.myhome.api.components.account.entity;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.myhome.api.components.house.entity.House;
import com.myhome.api.components.member.entity.Member;
import com.myhome.api.components.recipe.entity.Recipe;
import lombok.Data;

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

@Table(name = "account")
@Entity
@Data
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Integer id;

    @Column(name = "email")
    private String email;

    @Column(name = "password")
    private String password;

    @Column(name = "token")
    private String token;

    @OneToMany(
            cascade = {CascadeType.ALL},
            orphanRemoval = true,
            mappedBy = "fkAccountId")
    @JsonBackReference
    private Set<Member> members;
}
package com.myhome.api.components.member.entity;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.myhome.api.components.account.entity.Account;
import com.myhome.api.components.meal.entity.Meal;
import com.myhome.api.components.rating.entity.Rating;
import lombok.Data;

import javax.persistence.*;
import java.util.Set;

@Table(name = "member")
@Entity
@Data
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "icon")
    private Integer icon;

    @ManyToOne
    @JoinColumn(name = "fkAccountId", nullable = false)
    @JsonManagedReference
    private Account fkAccountId;

    @OneToMany(
            cascade = {CascadeType.ALL},
            orphanRemoval = true,
            mappedBy = "fkMemberId")
    @JsonBackReference
    private Set<Meal> meals;

    @OneToMany(
            cascade = {CascadeType.ALL},
            orphanRemoval = true,
            mappedBy = "fkMemberId")
    @JsonBackReference
    private Set<Rating> ratings;
}

我的问题是:

  1. 为什么会发生这种情况,即使在我添加食谱和房屋之间的联系之前它并没有发生?
  2. 我该如何解决?
  3. 原因是什么?

Why is this happening

这是由于 toString() 方法同时存在于 类 并形成循环依赖。这导致 AccountMember 的 toString() 方法之间的无限递归调用。

考虑这 2 个简单的 类。 Lombok 的 @Data 默认为所有字段生成 toString 方法。

class Member {
    String name;
    Account account;

    @Override
    public String toString() {
        return "Member{" +
                "name='" + name + '\'' +
                ", account=" + account.toString() + //Although string concatenation calls toString() on instance, I thought of adding it to call it out
                '}';
    }
}

class Account {
    String id;
    Member member;

    @Override
    public String toString() {
        return "Account{" +
                "id='" + id + '\'' +
                ", member=" + member.toString() + //Although string concatenation calls toString on instance, I thought of adding it to call it out
                '}';
    }
}

public static void main(String[] args) {
        Account account = new Account();
        Member member  = new Member();
        account.id="1";
        account.member=member;

        member.name ="XYZ";
        member.account=account;

        System.out.println(account);
    }

当您在 类 之一上调用 toString 方法时,比如说 Account 它将依次调用 MembertoString 方法并且循环重复直到您 运行 堆栈内存不足。这是堆栈跟踪:

Exception in thread "main" java.lang.WhosebugError
    at java.lang.StringBuilder.append(StringBuilder.java:136)
    at com.javainuse.main.Member.toString(AnotherMain.java:23)
    at java.lang.String.valueOf(String.java:2994)
    at java.lang.StringBuilder.append(StringBuilder.java:131)
    at com.javainuse.main.Account.toString(AnotherMain.java:10)
    at java.lang.String.valueOf(String.java:2994)

How can I fix it?

从您的 lombok 中排除 类 之一的 toString 生成,这应该有效。refer this 我建议实体 类 根本不需要 toString。

What are the causes?

我想我没听懂。能详细点吗?