解决使用@ManyToMany查询数据时的死循环问题

目录
  • 使用@ManyToMany查询数据时的死循环
    • 一、在Role中加上@JsonIgnore注解
    • 二、将双向关联改为单向关联
  • 单向多对多@ManyToMany的使用和理解

使用@ManyToMany查询数据时的死循环

初学使用spring data jpa,将问题记录

以User 和Role为例,两者为双向的多对多关系,即可以通过User查询到Role信息,也可以通过Role查询到User信息

首先要明白为什么会出现死循环这个问题,造成这个死循环的原因是因为查询User时,包含了Role属性,Role中又需要查询除user属性,这个不是spring data jpa 的问题,而是只要代码里互相关联都会造成这种情况,解决这种情况的方法我大概研究出了两种

一、在Role中加上@JsonIgnore注解

代码如下

User.java

package com.example.demo.entity;
import lombok.Data;
import javax.persistence.*;
import java.util.Set;

/**
 * @author lidai
 * @date 2018/10/23 13:53
 */
@Entity
@Data
@Table(name = "t_user")
public class User {

    @Id
    private String userId;
    private String username;
    private String password;

    @ManyToMany(cascade = CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(name = "t_user_role",
            joinColumns = @JoinColumn(name = "user_id",referencedColumnName = "user_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id",referencedColumnName = "role_id"))
    private Set<Role> roleSet;
}

Role.java

package com.example.demo.entity;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import javax.persistence.*;
import java.util.Set;

/**
 * @author lidai
 * @date 2018/10/29 14:15
 */
@Entity
@Table(name = "t_role")
@Data
@EqualsAndHashCode(exclude = {"userSet"})
public class Role {

    @Id
    @GeneratedValue
    private String roleId;
    private String roleName;
    private String remark;

    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY,mappedBy = "roleSet")
    private Set<User> userSet;
}

很多初学者可能对@ManyToMany这个注解存在一些疑惑,下面给出我的理解仅供参考

@ManyToMany代表多对多的关联关系

cascade 属性

  • CascadeType.ALL:级联包含所有持久化方法
  • CascadeType.PERSIST只有A类新增时,会级联B对象新增。若B对象在数据库存(跟新)在则抛异常(让B变为持久态)
  • CascadeType.MERGE指A类新增或者变化,会级联B对象(新增或者变化)
  • CascadeType.REMOVE只有A类删除时,会级联删除B类;

@JoinTable关联中间表,如User与Role的中间表为t_user_role

  • name:中间表名
  • JoinColumns:中间表与第一张表关联的外键(第一张表在user中即为user表)
  • inverseJoinColumns:与JoinColumns类似,为第二张表关联的外键

fetch

  • FetchType.EAGER:立即加载
  • FetchType.LAZY:懒加载

mappedBy = "roleSet":roleSet几位User表中的List<Role>属性名

以上为第一种解决方法

二、将双向关联改为单向关联

删除Role表中的如下代码即可

    @JsonIgnore
    @ManyToMany(fetch = FetchType.LAZY,mappedBy = "roleSet")
    private Set<User> userSet;

只不过单向关联时不能通过Role查询到User的信息

单向多对多@ManyToMany的使用和理解

  • 单向多对多:就是一个实体类可以获取到另外一个实体类
  • 多对多:一个员工可以拥有多个角色,一个角色可以对应多个员工
    //角色单向多对多:配置中间表
    //多对多:一个员工可以拥有多个角色,一个角色可以对应多个员工
    @ManyToMany(fetch = FetchType.LAZY)//配置懒加载
    //JoinTable是中间表表名,joinColumns指定中间表中关联自己ID的字段,  joinColumn是列名,inverseJoinColumns表示中间表中关联对方ID的字段。
    @JoinTable(name = "employee_role",joinColumns = @JoinColumn(name = "employee_id"),
            inverseJoinColumns = @JoinColumn(name = "role_id"))
    @JsonIgnore //生成json是忽略这个属性(数据大多,全部拿到没有意义,还有可能造成死循环)
    //将角色设置进来 有多个角色不能重复
    private Set<Role> roles = new HashSet<>();

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • spring jpa ManyToMany原理及用法详解

    1.java和jpa 中所有的关系都是单向的.这个关系数据库不同,关系数据库,通过外键定义并查询,使得反向查询总是存在的. 2.JPA还定义了一个OneToMany关系,它与ManyToMany关系类似,但反向关系(如果已定义)是ManyToOne关系. OneToMany与JPA中ManyToMany关系的主要区别在于,ManyToMany总是使用中间关系连接表来存储关系, OneToMany可以使用连接表或者目标对象的表引用中的外键源对象表的主键. @OneToMany(cascade =

  • 关于@OnetoMany关系映射的排序问题,使用注解@OrderBy

    目录 Spring里面一对多的关系可以用@OnetoMany注解来实现 来看看我的这个例子 看一下具体是怎么使用 最后我的代码 Entity One-to-Many 排序设置 Spring里面一对多的关系可以用@OnetoMany注解来实现 然后在实际使用中,如果要对从属对象按条件排序该怎么处理呢?可以用注解来实现的也就是@OrderBy 来看看我的这个例子 一个Product对象,里面有个OnetoMany关系对应到多张图片,然后我这个图片在后台要支持排序,所以我就在Picture这个类里面加

  • 对Jpa中Entity关系映射中mappedBy的全面理解

    目录 对Jpa Entity关系映射中mappedBy的理解 对于mappedBy复习下 举例说明 Spring-jpa中mappedBy的作用 使用@JoinColumn存在的问题 使用mappedBy 对Jpa Entity关系映射中mappedBy的理解 mappedBy 单向关系不需要设置该属性,双向关系必须设置,避免双方都建立外键字段数据库中1对多的关系,关联关系总是被多方维护的即外键建在多方,我们在单方对象的@OneToMany(mappedby="")把关系的维护交给多方

  • SpringBoot + JPA @ManyToMany的操作要点说明

    目录 SpringBoot + JPA @ManyToMany 要点 对应的Entity的建立 Junit的测试 JPA中ManyToMany关系问题 解决办法 SpringBoot + JPA @ManyToMany 要点 这里主要时记录下此种方法的注意事项. 环境 :mysql 引擎为innoDB ,否则没有事务的说法的. #不加这句则默认为myisam引擎 spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDial

  • 解决使用@ManyToMany查询数据时的死循环问题

    目录 使用@ManyToMany查询数据时的死循环 一.在Role中加上@JsonIgnore注解 二.将双向关联改为单向关联 单向多对多@ManyToMany的使用和理解 使用@ManyToMany查询数据时的死循环 初学使用spring data jpa,将问题记录 以User 和Role为例,两者为双向的多对多关系,即可以通过User查询到Role信息,也可以通过Role查询到User信息 首先要明白为什么会出现死循环这个问题,造成这个死循环的原因是因为查询User时,包含了Role属性,

  • 关于MyBatis 查询数据时属性中多对一的问题(多条数据对应一条数据)

    数据准备 数据表 CREATE TABLE `teacher`( id INT(10) NOT NULL, `name` VARCHAR(30) DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=INNODB DEFAULT CHARSET=utf8; INSERT INTO `teacher`(id,`name`) VALUES(1,'大师'); CREATE TABLE `student`( id INT(10) NOT NULL, `name` VARCHAR

  • 解决python2.7 查询mysql时出现中文乱码

    问题: python2.7 查询或者插入中文数据在mysql中的时候出现中文乱码 --- 可能情况: 1.mysql数据库各项没有设置编码,默认为'latin' 2.使用MySQL.connect的时候没有设置默认编码 3.没有设置python的编码,python2.7默认为'ascii' 4.没有解码 --- 解决方法: 1.设置mysql的编码 ubuntu执行下列语句: ** sudo vim /etc/mysql/my.cnf ** 然后在里面插入语句: [client] default

  • Android中的sqlite查询数据时去掉重复值的方法实例

    1.方式一: /** * 参数一:是否去重 * 参数二:表名 * 参数三:columns 表示查询的字段,new String[]{MODEL}表示查询该表当中的模式(也表示查询的结果) * 参数思:selection表示查询的条件,PHONE_NUMBER+" = ?" 表示根据手机号去查询模式 * 参数五:selectionArgs 表示查询条件对应的值,new String[]{phoneNumber}表示查询条件对应的值 * 参数六:String groupBy 分组 * 参数

  • MyBatis查询数据,赋值给List集合时,数据缺少的问题及解决

    目录 MyBatis查询数据赋值给List集合数据缺少 解决办法 Mybatis查询时数据丢失的问题 经过排查得出结论 解决办法 MyBatis查询数据赋值给List集合数据缺少 今天在使用MyBatis查询数据时,发现查出来的数据和List集合的大小不一致,如下图所示,Total为3,但是list集合size为2.   List<ArticleCommentToShow> commentsByArticleId = articleCommentService.getCommentsByArt

  • jQuery Easyui学习教程之实现datagrid在没有数据时显示相关提示内容

    本示例实现easyui datagrid加载/查询数据时,如果没有相关记录,则在datagrid中显示没有相关记录的提示信息,效果如下图所示 本实例要实现如下图所示的效果: 本示例easyui版本为1.3.4,如果运行后没有效果,自己检查easyui版本 不同版本对appendRow和mergeCells支持不一样,参数不一致什么的. 无法隐藏分页导航容器,可以用chrome开发工具或者firebug查看分页导航容器的样式和原始datagrid table表格的关系. 源代码如下 $(funct

  • 解决PHP里大量数据循环时内存耗尽的方法

    最近在开发一个PHP程序的时候遇到如下一问题: PHP Fatal error: Allowed memory size of 268 435 456 bytes exhausted 错误信息显示允许的最大内存已经耗尽.遇到这样的错误起初让我很诧异,但转眼一想,也不奇怪,因为我正在开发的这个程序是要用一个foreach循环语句在一个有4万条记录的表里全表搜索具有特定特征的数据,也就是说,一次要把4万条数据取出,然后逐条检查每天数据.可想而知,4万条数据全部加载到内存中,内存不爆才怪. 毕竟编程这

  • 快速解决mysql导数据时,格式不对、导入慢、丢数据的问题

    如果希望一劳永逸的解决慢的问题,不妨把你的mysql升级到mysql8.0吧,mysql8.0默认的字符集已经从latin1改为utf8mb4,因此现在UTF8的速度要快得多,在特定查询时速度提高了1800%! 但是如果时间等不及,就先用下面的办法快速解决一下. 问题一:格式不对(常出现时间格式不对的情况): 方法1:将excel文件另存为csv,再导入数据库: 方法2:导入的第一步时,默认编码方式是65001(UTF-8),可以尝试选择[10008 (MAC - Simplified Chin

  • 解决mybatis三表连接查询数据重复的问题

    此问题的产生,主要是数据库的字段名一样导致 三张表 DOCTOR JOB OBJECT 有问题的查询语句和查询结果是: SELECT d.*,j.*,o.* from (select d.*,rownum r from DOCTOR d where rownum<=6) d join job j on d.job_id=j.id join object o on o.id=d.object_id where r>0 <img src="https://img-blog.csdn

  • vue渲染大量数据时卡顿卡死解决方法

    目录 1. 问题描述 2. 常见的解决方案 3. 解决方案流程图 4. 代码 1. 问题描述 由于业务需求,需要在一个页面中点击查询按钮时加载出所有的数据,但数据量有近10万条,渲染出现卡顿,页面卡死. 2. 常见的解决方案 - 自定义中间层 自定义nodejs中间层,获取并拆分这10w条数据, 前端对接nodejs中间层,而不是服务器 缺点:成本高 - 虚拟列表 只渲染可视区域DOM,其他隐藏区域不显示,只用div撑起高度,随着浏览器滚动,创建和销毁DOM. 虚拟列表实现起来非常复杂,可借用第

随机推荐