簡體   English   中英

StackOverflowError Springboot OneToMany 雙向映射

[英]StackOverflowError Springboot OneToMany BiDirectional Mapping

我目前正在編寫一個項目,這需要我在兩個實體之間進行 map:一個帳戶和一個成員。 一個帳戶可以有多個成員,而一個成員只能有一個帳戶。
在我完成雙向編碼后,一切正常,我得到了我想要的響應,只有成員。

從這里開始,問題開始了:
我開始編寫“食譜”的方式。 食譜以多對一關系連接到“house”,然后它與“account”具有 1:1 的關系。 實現這個之后,我發現了一個 StackOverFlow,它以前不存在。 (帳戶和會員之間的一種)

下面是數據庫中所述結構的圖像。 配方 -> 房子 -> 帳戶。 (存在關系和表格,頂部帶有藍色十字,但並未真正連接) 企業風險管理

我的實體如下所示:

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. 原因是什么?

為什么會這樣

這是由兩個類中都存在toString()方法並形成循環依賴引起的。 這會導致AccountMember的 toString() 方法之間的無限遞歸調用。

考慮這兩個簡單的類。 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方法,並且循環重復,直到您用完堆棧 memory。 這是堆棧跟蹤:

Exception in thread "main" java.lang.StackOverflowError
    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)

我該如何解決?

為您的 lombok 中的一個類排除 toString 生成,這應該可以工作。 參考這個

原因是什么?

我想我不明白。 你能詳細說明一下嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM