单个实体上的多个@ManyToMany会导致交叉连接

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单个实体上的多个@ManyToMany会导致交叉连接相关的知识,希望对你有一定的参考价值。

我有一个用户实体。

@Entity
@Table(name = "t_login_user")
public class User  extends Auditable<Long> implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private Long id;

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

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

    @OneToOne(fetch = FetchType.EAGER, optional = false)
    @JoinColumn(name="primary_role_id")
    private Role primaryRole;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "t_login_user_role_map", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private List<Role> roles;

}

我的角色实体是

@Entity
@Table(name = "t_login_role")
public class Role extends Auditable<Long> implements Serializable {


@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="role_id")
private Long roleId;

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

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "t_login_role_priv_map", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "priv_id"))
private List<Privilege> privileges;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "t_login_role_menu_map", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "menu_id"))
private List<Menu> menus;

}

我的菜单实体是

@Entity
@Table(name = "t_login_menu")
public class Menu extends Auditable<Long> implements Serializable{


    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    private Long id;

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

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

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


}

如您所见,我的角色有多个权限和多个菜单。我遇到的问题是,当我有一个类似的代码

LoggedinUser liu = (LoggedinUser)authentication.getPrincipal();
List<Menu> menus = liu.getPrimaryRole().getMenus();

如果我有两个权限说READ_DATA和WRITE_DATA和三个菜单1.主页2.USER 3.PROFILE

我的menu变量的值为[HOME,HOME,USER,USER,PROFILE,PROFILE](即2个权限* 3个角色)

我怀疑这是因为我的Role实体有多个@ManyToMany注释。

我试图在线搜索和Stackoverflow但没有结果。有人面对这个问题吗?我做了一些根本错误的事情吗?

答案

好的。我理解交叉连接发生的位置。由于ManyToMany都加载了EAGER,因此这就是Cross Join发生的地方。

如果我改为LAZY Load,那么问题就会消失。轻微的性能受到LAZY负载的影响,但这很好,因为我只做了一次并将结果存储在会话中。

以上是关于单个实体上的多个@ManyToMany会导致交叉连接的主要内容,如果未能解决你的问题,请参考以下文章

ManyToMany 关系导致 *** 错误

Doctrine Symfony ManyToMany 将表作为 OneToMany 连接到其他表

Doctrine2 ManyToMany 自引用

使用命名查询时的 ManyToMany NOT NULL 检查约束

ManyToMany 属性的 SELECT 上的 JPQL Hibernate SQLException

OneToMany 和 ManyToMany 单向关系的区别