Hibernate注解:多对多异常

?org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags异常

?

我的User中开始的时候已经有了一个@ManyToMany了,具体配置如下:

?

@ManyToMany(fetch = FetchType.EAGER)
    @NotFound(action = NotFoundAction.IGNORE)
    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    @JoinTable(name = "user_role",joinColumns = {@JoinColumn(name = "user_id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id")})
    public List<Role> getRoleList() {
        return roleList;
    }

?运行程序完全正常。可是当我再在User中再添加了一个@ManyToMany,结果就出现了以上异常:

?

?org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags。

?

    @ManyToMany(fetch = FetchType.EAGER)
    @NotFound(action = NotFoundAction.IGNORE)
    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    @JoinTable(name = "user_menu",joinColumns = {@JoinColumn(name = "user_id")},
            inverseJoinColumns = {@JoinColumn(name = "menu_id")})
    public List<Menu> getMenuList() {
        return menuList;
    }

?然后,在网上查找了一下资料,发现了问题所在:

?

1.当一个实体类中需要映射两个集合实体的时候,只允许有一个集合实体的fetch的FetchType设置为EAGER,另外的一个设置为LAZY;或者也可以用@IndexColumn。

2.在其中一个get方法上做如下注解:

@ManyToMany(fetch = FetchType.EAGER)
    @Fetch(value=FetchMode.SUBSELECT)
    @NotFound(action = NotFoundAction.IGNORE)
    @JsonIgnore
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    @JoinTable(name = "user_menu",joinColumns = {@JoinColumn(name = "user_id")},
            inverseJoinColumns = {@JoinColumn(name = "menu_id")})
    public List<Menu> getMenuList() {
        return menuList;
    }

?3.还有一种方法就是,将另一个list集合改为Set集合。

?

最后,看看FetchTypeFetchMode?的区别:

两者都是设定关联对象的加载策略。

FetchType是JPA标准的通用加载策略注解属性,FetchMode?是Hibernate自有加载策略注解属性。

FetchType可选值意义与区别如下:

FetchType.LAZY:?懒加载,在访问关联对象的时候加载(即从数据库读入内存)

FetchType.EAGER:立刻加载,在查询主对象的时候同时加载关联对象。

FetchMode可选值意义与区别如下:

@Fetch(FetchMode.JOIN):?始终立刻加载,使用外连(outer?join)查询的同时加载关联对象,忽略FetchType.LAZY设定。

@Fetch(FetchMode.SELECT)?:默认懒加载(除非设定关联属性lazy=false),当访问每一个关联对象时加载该对象,会累计产生N+1条sql语句

@Fetch(FetchMode.SUBSELECT)??默认懒加载(除非设定关联属性lazy=false),在访问第一个关联对象时加载所有的关联对象。会累计产生两条sql语句。且FetchType设定有效。?

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。