问题描述:在使用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
}