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 groupList,在遍历集合中,输出一个group实例的时候,List

menuList字段也将输出,因为是双向多对多的关联查询,每一个group实例也会输出List 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 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 menuList;

    //getter和setter
}

你可能感兴趣的:(工具类,SpringBoot)