SpringBoot的@ManyToMany出现异常: Could not write JSON: Infinite recursion (StackOverflowError)

问题描述:在使用SpringBoot进行多对多的关联查询的时候,写数据回页面时出现异常,如下所示:

Failed to write HTTP message:
org.springframework.http.converter.HttpMessageNotWritableException: 
Could not write JSON: Infinite recursion (StackOverflowError); 
nested exception is com.fasterxml.jackson.databind.JsonMappingException: 
Infinite recursion (StackOverflowError) (through reference chain: 
org.hibernate.collection.internal.PersistentBag[0]->
com.XXX.entity.Menu["groupList"]->
org.hibernate.collection.internal.PersistentBag[0]->
com.XXX.entity.Group["menuList"]
.......
//循环打印出上面四行的内容

原因是:Menu类中有一个字段List<Group> groupList,在遍历集合中,输出一个group实例的时候,List<Menu> menuList字段也将输出,因为是双向多对多的关联查询,每一个group实例也会输出List<Menu> menuList字段值,因此一直递归下去直到栈溢出报错,反之,从group中读menu也是一样的道理。

解决方法:在被维护的表里面,表示其他表的外键上添加@JsonIgnore注解。


附:@ManyToMany的用法

//Menu表
import lombok.Data;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;

import javax.persistence.*;
import java.io.Serializable;
import java.util.List;

@Entity
@Data
@Table(name = "sys_menu")
public class Menu implements Serializable {

    private static final long serialVersionUID = 7066921546255113861L;
    /**
     * 主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    /**
     * 菜单名字
     */
    @Column(nullable = false, name = "name")
    private String name;

    /**
     * 多对多的关系,理论上是维护关系的一方
     */
    @ManyToMany(cascade = {CascadeType.MERGE,CascadeType.REFRESH},fetch = FetchType.EAGER)
    @JoinTable(
            name = "sys_group_menu",
            joinColumns = {
                    @JoinColumn(name = "menu_id",referencedColumnName = "id")
            },
            inverseJoinColumns = {
                    @JoinColumn(name = "group_id",referencedColumnName = "id")
            }
    )
    private List<Group> groupList;

    //getter和setter
}
//Group表

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;

import javax.persistence.*;
import javax.validation.constraints.NotEmpty;
import java.io.Serializable;
import java.util.List;

@Entity
@Data
@Table(name = "sys_group")
public class Group implements Serializable {

    private static final long serialVersionUID = 8528658622365738309L;


    /**
     * 主键
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    /**
     * 组别
     */
    @NotEmpty(message = "组名不能为空!")
    @Column(nullable = false,name = "name")
    private String name;

    /**
     * 多对多的关系,被维护的一方
     */
     //【重点在这里】
    @JsonIgnore
    @ManyToMany(fetch = FetchType.EAGER, mappedBy = "groupList")
    @NotFound(action = NotFoundAction.IGNORE)
    private List<Menu> menuList;

    //getter和setter
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值