当前位置: 首页 > 知识库问答 >
问题:

多双向映射

涂选
2023-03-14

我的实体如下所示:

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

共有1个答案

慕容光启
2023-03-14

为什么会这样

这是由于类中都存在toString()方法并形成循环依赖关系造成的。这将导致帐户成员的toString()方法之间的无限递归调用

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

class Member {
    String name;
    Account account;

    @Override
    public String toString() {
        return "Member{" +
                "name='" + name + '\'' +
                ", account=" + account +
                '}';
    }
}

class Account {
    String id;
    Member member;

    @Override
    public String toString() {
        return "Account{" +
                "id='" + id + '\'' +
                ", member=" + member +
                '}';
    }
}

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方法时,假设帐户,它将依次调用成员toString方法,循环重复,直到您用完堆栈内存。这是堆栈跟踪:

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生成,这样应该可以工作。参考此

原因是什么?

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

 类似资料:
  • 1. 前言 通过本节课程的学习,你将发现关联对象之间的微妙关系。相信这种关系对你更深入地认识 HIbernate 有很大的帮助。 通过本节课程,你将了解到: 多对多双向关联映射中哪一方是关系维系者; 级联操作与关系维系者。 2. 关系维系者 新学期开始了,同学们选择了各自喜欢的课程,现在为学生添加选修课程的任务就要落在 Hibernate 的身上。一起来看看 Hibernate 是如何完成这个任务

  • 问题内容: 我正在寻找一种存储键值对的方法。我需要双向查询,但同时我需要为同一个键存储多个值。换句话说,类似于BidiMap,但是对于每个键,可以有多个值。例如,它需要能够保存以下对:“ s1”-> 1,“ s2”-> 1,“ s3”-> 2,并且我需要能够将值映射到每个键,并且对于每个值,获取与其关联的所有键。 问题答案: 因此,你需要多对多关系的支持吗?你可以得到的最接近的是Guava,Mul

  • 问题内容: 我正在努力进行双向多对多映射,其中顺序在一侧很重要,而在另一侧则不重要。 我有两节课:程序和学生。 一个程序有很多学生,顺序很重要。 程序A 约翰 莎莉 赛斯 程式B 亚历克斯 赛斯 艾米 约翰 一个学生有很多程序,但是顺序在这里并不重要。 John 程序A 程序B 莎莉 程序A 赛斯 程序A 程式B 亚历克斯 程式B 艾米 程式B 因此,似乎我可以在程序和学生之间建立双向的多对多关联

  • 下面的例子中,我有一个单独的域层和一个单独的持久层。我使用Mapstruct进行映射,当从域映射到实体或从实体映射到域时,会出现堆栈溢出,因为双向引用总是被调用- 用于映射的类非常基本

  • 我有两张桌子。后 和喜欢 在这些对象之间进行hibernate注释映射,以便在类似于Post bean的。。。。 就像豆子一样 问题 该关联是否由Post{@OneToOne}和like{@ManyToOne}正确? 获取类型是Lazy,但仍然得到依赖循环。为什么? 尝试 要删除依赖关系循环,我尝试了 {@xmltransive} {@JsonIgnore} {@JsonManagedRefere

  • 1. 前言 本节课程和大家一起聊聊一对多关联映射。通过本节课程,你将了解到: 如何实现一对多关联映射; 如何实现双向一对多关联映射; 关联映射中的级联操作。 2. 一对多关联映射 关系型数据库中表与表中的数据存在一对多(或多对一)关系。 如学生表、班级表。一个班级有多个学生,多个学生可以在同一个班级。 一对多或多对一本质上是一样的,如同一块硬币的正面和反面,只是看待事物的角度不同而已。 数据库中有