hibernate注解联表查询以及联表导致的死循环

好不容易解决了hibernate注解导致联表查询死循环的问题,这里记录一下

BaseEntity
@Setter
@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity implements Serializable {
	// ...
	@Column(name = "create_time")
    @CreationTimestamp
    private Timestamp createTime;

    @Column(name = "update_time")
    @UpdateTimestamp
    private Timestamp updateTime;

    public String toString() {
        ToStringBuilder builder = new ToStringBuilder(this);
        Field[] fields = this.getClass().getDeclaredFields();
        try {
            for (Field f : fields) {
                f.setAccessible(true);
                builder.append(f.getName(), f.get(this)).append("\n");
            }
        } catch (Exception e) {
            builder.append("toString builder encounter an error");
        }
        return builder.toString();
    }

    public @interface Create {
    }

    public @interface Update {
    }
}
SysMember
@Entity
@Data
@Table(name = "sys_member")
public class SysMember extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @NotNull(groups = {Update.class})
    private Long id;

	// 用户可以主动查看权限,fetch为主动,解决lazy导致的获取roleSet时sql连接已断开的问题
    @ManyToMany(fetch = FetchType.EAGER)
    @ApiModelProperty(value = "用户权限")
    // JoinTable 设置中间表,joinColumns为当前实体的标识,inverseJoinColumns为被查询的实体标识
    @JoinTable(name = "sys_role_member",
            joinColumns = {@JoinColumn(name = "member_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
    private Set<SysRole> roleSet;

	// 重写equals方法,主要是jpa在对数据进行更新时会以equals为判断依据,不重写容易出现各种奇怪的问题
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        SysMember role = (SysMember) o;
        return Objects.equals(id, role.id);
    }

	// copy方法,主要是用于设定值的时候去除空值
    public void copy(SysMember source) {
        BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
SysMenu
@Entity
@Data
@Table(name = "sys_menu")
public class SysMenu extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @NotNull(groups = {Update.class})
    private Long id;

	// 关键的JsonIgnore,这个注解用于解决调用api时,roleSet无限循环查询,最终导致内存溢出或者时json转换错误
    @JsonIgnore
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "sys_role_menu",
            joinColumns = {@JoinColumn(name = "menu_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
    private Set<SysRole> roleSet;

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

    public void copy(SysMenu source) {
        BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
    }
}
SysRole
@Entity
@Data
@Table(name = "sys_role")
public class SysRole extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @NotNull(groups = {Update.class})
    private Long id;
	
	// 权限可以主动查询菜单,便于调取,
    @ManyToMany(fetch = FetchType.EAGER)
    @ApiModelProperty(value = "权限菜单")
    @JoinTable(name = "sys_role_menu",
            joinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "menu_id", referencedColumnName = "id")})
    private Set<SysMenu> menuSet;

	// 权限通过绑定相应的member实体中的roleSet数据
    @JsonIgnore
    @ApiModelProperty(value = "用户权限")
    @ManyToMany(mappedBy = "roleSet")
    private Set<SysMember> memberSet;

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

    public void copy(SysRole source) {
        BeanUtil.copyProperties(source, this, CopyOptions.create().setIgnoreNullValue(true));
    }
}

通过主要的几个注释
@ManyToMany
@ManyToOne
@OneToMany来联表查询
通过设定
@JsonIgnore
忽略json转换问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值