问题描述:

用户、角色、权限表中,用户多对多角色,角色多对多权限。

User Entity:

@ManyToMany(fetch = FetchType.EAGER) // 立即从数据库中进行加载数据;
@JoinTable(name = "sys_user_role", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns = {
@JoinColumn(name = "role_id") })
private List<SysRole> roles;// 一个用户具有多个角色

Role Entity:

// // 角色 -- 权限关系:多对多关系;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "sys_role_permission", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {
@JoinColumn(name = "permission_id") })
private List<SysPermission> permissions;
// 用户 - 角色关系定义;
@ManyToMany
@JoinTable(name = "sys_user_role", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {
@JoinColumn(name = "uid") })
private List<UserInfo> users;// 一个角色对应多个用户

Permission Entity:

@ManyToMany
@JoinTable(name = "sys_role_permission", joinColumns = {
@JoinColumn(name = "permission_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
private List<SysRole> roles;

执行shiro时报错:org.hibernate.HibernateException: cannot simultaneously fetch multiple bags

原因:

在说解决cannot simultaneously fetch multiple bags异常之前,我先说下抓取策略

注解@Fetch(FetchMode.?)抓取策略有三种

1、FetchMode.JOIN(默认的抓取策略),采用外连接的形式,left outer join ... on

2、FetchMode.SELECT 会另外发送一条sql语句加载当前对象的关联实体

3、FetchMode.SUBSELECT 会另外发送一条select语句抓取前面查询到的所有实体对象的关联实体

通过Hibernate输出的SQL日志看成,个人感觉2、3的差别不是太大 ,都是另起select语句查询与当前某个实体相关联的其他实体。

下面是我写的一个简单DEMO,主要来验证抓取策略和异常的处理方法

表结构

人员表  tb_person

+-------------+

| Field       |

+-------------+

| person_id   |

| person_age  |

| person_name |

+-------------+

一个人员可以有多个邮箱,邮箱表,人-邮箱是一对多的关系tb_person_email

+-----------+

| Field     |

+-----------+

| id        |

| person_id |

| address   |

+-----------+

事件表,一个人可以有多个事件,一个事件也可有多个人处理,是多对多关系tb_event,tb_person_event

+-------------+

| Field       |

+-------------+

| event_id    |

| event_title |

| event_date  |

+-------------+

+-----------+

| Field     |

+-----------+

| event_id  |

| person_id |

+-----------+

要执行的方法是:搜索人,以及相关的事件和邮件。

person.java

第一种写法,采用默认join抓取策略,进行强制抓取person所有关联对象的方式

如果这样写的情况下, 就会报cannot simultaneously fetch multiple bags异常,从SQL日志分析,hibernate是这样执行的

select *

from TB_PERSON tp left outer join TB_PERSON_EMAIL tpe1 on tp.person_id = tpe1.person_id  left outer join TB_PERSON_EMAIL tpe2 on tpe1.id = tpe2.id  left outer join TB_PERSON_EVENT tpet on tp.person_id = tpet.person_id

left outer join TB_EVENT te on tpet.event_id = te.event_id

where tp.person_id = 2;

输出的记过,就会出现两个同样的email实体列,所以就报上述异常。

当持久框架抓取一方的对象时,同时加载多方的对象放进容器中,多方又可能与关联其它对象,Hibernate实现的JPA,默认最高抓取深度含本身级为四级(它有个属性配置是0-3),若多方(第二级)存在重复值,则第三级中抓取的值就无法映射,按照这个道理,就应该报出无法同时加载多个包之异常。

解决方案:

1.将List变为Set

2.fetch=FetchType.LAZY

3.@Fetch(FetchMode.SUBSELECT)

这种方法就是在不修改原结构注释的情况下,可以修改一下抓取策略,分开select实体,这样就不会出现重复列现象。

个人感觉还是不错的方法,打算就用它了。

4.@IndexColumn

Hibernate:cannot simultaneously fetch multiple bags 解决方案相关推荐

  1. Hibernate中:cannot simultaneously fetch multiple bags的问题

    在利用hibernate做关系映射的时候,报错(最主要部分) nested exception is org.hibernate.loader.MultipleBagFetchException: c ...

  2. 解决org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

    报错:org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags 出错原因:当( ...

  3. cannot simultaneously fetch multiple bags 的解决方法

    病理特征:Caused by: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags, 堆栈信息:or ...

  4. cannot simultaneously fetch multiple bags

    JPA Caused by: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags -----引用来自 ...

  5. cannot simultaneously fetch multiple bags 异常的解决办法

    异常信息如下: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags .. ...

  6. “cannot simultaneously fetch multiple bags”的解决方法

    Java代码   @OneToMany(mappedBy = "customer",cascade = {CascadeType.ALL},fetch = FetchType.LA ...

  7. go语言,安装包fetch error 问题解决方案

    go语言,安装包fetch error 问题解决方案 参考文章: (1)go语言,安装包fetch error 问题解决方案 (2)https://www.cnblogs.com/Geek-xiyan ...

  8. pynlpir更新license Error: unable to fetch newest license解决方案

      大家好,我是爱编程的喵喵.双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中.从事机器学习以及相关的前后端开发工作.曾在阿里云.科大讯飞.CCF等比赛获得多次Top名次.喜 ...

  9. Hibernate中的fetch

    fetch参数指定了关联对象抓取的方式是select查询还是join查询,select方式时先查询返回要查询的主体对象(列表),再根据关联外键id,每一个对象发一个select查询,获取关联的对象,形 ...

最新文章

  1. 安全与加密-使用gpg和openssl实现加密与解密
  2. 你一定需要知道的高阶JAVA枚举特性!
  3. 看了毁你三观的PCB设计理论 高速PCB外层还要不要覆铜了
  4. 题目3:文本文件单词的检索与计数(实验准备)
  5. tensorflow随笔-constant
  6. 彻底理解 Python 生成器
  7. 数据仓库之电商数仓-- 3.3、电商数据仓库系统(DWT层)
  8. 主题图标_iPhone一键更换主题、图标神器
  9. mysql特有语法_MySQL 独有SQL语法汇总(一)
  10. C#中如何调用动态链接库DLL
  11. Qt 点击任意子控件,背景选中 选中背景
  12. SCM供应链管理系统有源码可以共享一下吗?
  13. 苹果ID登陆第三方有漏洞?硬核!Gartner报告腾讯云数据库增速国内第一;“小米快递”商标注册,这是要入局物流领域?...
  14. 杜兰大学计算机专业,杜兰大学计算机科学专业详解.docx
  15. win10电脑新建Excel工作簿,后缀变成xlsm(正常本应该是xlsx)的解决办法
  16. Docker常用命令(启动、镜像相关、容器相关、文件拷贝、目录挂载、查看容器IP地址、Docker备份与恢复)
  17. 小数化分数 思路及代码模板 c++实现
  18. windows如何获取端口号
  19. 关于DNS的配套工具
  20. CRLF和LF的区别

热门文章

  1. 商标注册申请怎么填写商品名称
  2. ps中怎么导出tif_PS中图像常用的2种存储格式——TIFF/JPEG
  3. oracle sqlplus 退格,Oraclesqlplus中方向键、退格键的使用
  4. 设计模式六大原则——单一职责原则(SRP)
  5. Kubernetes 二进制安装详细步骤
  6. 针对双非学生计算机保研信息分享
  7. 如何在 Visual Paradigm 中创建流程图丨使用教程
  8. 关于结构方程模型SEM评价指标
  9. 数组数据通过sql语句转为数据库表衔接到from或join后进行直接或关联查询
  10. 【Java 代码实例 14】BeanUtils用法详解,附源码分析