解决:JPA多对多查询死循环

遇到的错误:做权限时,3个表多对多关系查询,运行报错死循环,直接循环到内存溢出了

 

目录

1. 使用@JsonIgnore 或者 @JsonIgnoreProperties注解可防止死循环​

2. 检查你的实体类是否使用了lambok的@Data注解


这是我授权模块的表结构,可以看出都是多对多关系的

 

1. 使用@JsonIgnore 或者 @JsonIgnoreProperties注解可防止死循环

没时间描述原理了,直接帖正确的代码了

User.java 用户表

package com.lns.analysis.domain.primary;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.Date;
import java.util.Set;

/**
 * TODO: 用户
 */
@Getter
@Setter
@Entity
@Table(name = "T_SG_USER")
public class User {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Long id;

  @Column(name = "email")
  private String email;

  @Column(name = "enabled")
  private boolean enabled;

  @Column(name = "password")
  private String password;

  @Column(name = "username")
  private String username;

  @Column(name = "phone")
  private String phone;

  @ManyToMany
  @JoinTable(
      name = "T_SG_USERS_ROLES",
      joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
      inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
  private Set<Role> roles;

  @Column(name = "create_time")
  private Date createTime;

  @Column(name = "last_password_reset_time")
  private Date lastPasswordResetTime;
}

Role.java 权限角色表

package com.lns.analysis.domain.primary;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.Set;

/**
 * TODO: 角色
 *
 * @author zhaowenhao
 * @date 2020.04.15
 */
@Getter
@Setter
@Entity
@Table(name = "T_SG_ROLE")
public class Role {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private Long id;

  @Column(name = "name")
  private String name;

  @Column(name = "remark")
  private String remark;

  @Column(name = "data_scope")
  private String dataScope;

  @Column(name = "level")
  private int level;

  @JsonIgnore
  @ManyToMany(mappedBy = "roles")
  private Set<User> users;

  @ManyToMany
  @JoinTable(
      name = "T_SG_ROLE_MENUS",
      joinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")},
      inverseJoinColumns = {@JoinColumn(name = "menu_id", referencedColumnName = "id")})
  private Set<Menu> menus;

  @Column(name = "create_time")
  private Long create_time;

  @Column(name = "permission")
  private String permission;
}

Menu.java 权限菜单表

package com.lns.analysis.domain.primary;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.sql.Timestamp;
import java.util.Objects;
import java.util.Set;

/**
 * TODO: 菜单
 *
 * @author zhaowenhao
 * @date 2020.04.15
 */
@Getter
@Setter
@Entity
@Table(name = "T_SG_MENU")
public class Menu {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @NotNull(groups = {Update.class})
  private Long id;

  @NotBlank private String name;

  @Column(unique = true)
  private Long sort = 999L;

  @Column(name = "path")
  private String path;

  private String component;

  /** 类型,目录、菜单、按钮 */
  @Column(name = "type")
  private Integer type;

  /** 权限 */
  @Column(name = "permission")
  private String permission;

  @Column(unique = true, name = "component_name")
  private String componentName;

  private String icon;

  @Column(columnDefinition = "bit(1) default 0")
  private Boolean cache;

  @Column(columnDefinition = "bit(1) default 0")
  private Boolean hidden;

  /** 上级菜单ID */
  @Column(name = "pid", nullable = false)
  private Long pid;

  /** 是否为外链 true/false */
  @Column(name = "i_frame")
  private Boolean iFrame;

  @ManyToMany(mappedBy = "menus")
  @JsonIgnore
  private Set<Role> roles;

  @Column(name = "create_time")
  @CreationTimestamp
  private Timestamp createTime;

  public @interface Update {}

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Menu menu = (Menu) o;
    return Objects.equals(id, menu.id);
  }

  @Override
  public int hashCode() {
    return Objects.hash(id);
  }
}

2.如果配置了@JsonIgnore忽略了嵌套值,还是死循环,检查你的实体类是否使用了lambok

原因:使用lombak@data,@data里默认实现了很多方法,包括toString(),死循环在toString方法中

解决办法如下,把@Data 改为@Getter @Setter 只生成git,set方法

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值