首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >StackOverflowError Springboot OneToMany BiDirectional映射

StackOverflowError Springboot OneToMany BiDirectional映射
EN

Stack Overflow用户
提问于 2022-01-19 15:40:22
回答 1查看 751关注 0票数 0

我目前正在编写一个项目,它要求我在两个实体之间映射:一个帐户和一个成员。一个帐户可以有多个成员,而成员只能有一个帐户。

在我完成双向编码之后,一切都正常工作,我得到了我想要的响应,这是唯一的成员。

从这里开始,问题开始:

我开始用我的方式编写“食谱”。菜谱在ManyToOne关系中连接到"house",后者与“帐户”有1:1的关系。在实现这个之后,我发现了一个StackOverFlow,它以前并不存在。(帐户与会员之间的)

下面是数据库中所述结构的图像。菜谱-> House ->帐户。(上面有蓝色十字的关系和表是存在的,但并不是真正连接起来的)

我的实体看起来是这样的:

代码语言:javascript
复制
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;
}
代码语言:javascript
复制
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. 是什么原因?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-19 15:41:44

为什么会发生这种事

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

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

代码语言:javascript
复制
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方法,循环会重复,直到堆栈内存用完为止。这是堆栈:

代码语言:javascript
复制
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)

我怎样才能修好它?

将其中一个类的toString生成排除在lombok之外,这应该有效。refer this,我建议实体类不要使用toString。

的原因是什么?

我想我不明白。你能详细说明一下吗?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70773463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档