为没有 FetchType.EAGER 的用户分配角色

时间:2021-07-05 10:44:04

标签: java spring hibernate jpa

我有一个 @ManyToMany 表 enter image

role 表包含角色 ROLE_USERROLE_ADMIN 等。

下面我将展示如何在 userrole 表之间创建关系。

角色类

            @ManyToMany(mappedBy = "roleList", cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
            private List<User> userList = new ArrayList<>();


            public void addPerson(User user) {
                    userList.add( user );
                    user.getRoleList().add( this );
                }

用户类

            @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
            @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
            private List<RoleUser> roleUserList = new ArrayList<>();


            public void addRole(Role role) {
                    roleList.add(role);
                    role.getUserList().add( this );
                }

假设我已经在 role 表中有一个角色列表。现在我想创建一个用户并为其分配这些角色之一。

在这种情况下,我正在尝试执行以下操作:

我指定了FetchType.EAGER(这对我来说是不可取的。否则它不起作用),然后我在控制器中写入以下内容:

            Role role = serviceJpa.findRoleByRoleName("ROLE_USER");
            role.addUser(user);
            serviceJpa.saveRole(role);

查看一下,用户已经完美添加,角色也成功分配给了该用户。

但正如我之前所说,FetchType.EAGER 对我来说并不理想,因为我不想在访问角色表时获得一百万用户。

但如果我使用 FetchType.LAZY 则抛出异常:

<块引用>

消息 请求处理失败;嵌套异常是 org.hibernate.LazyInitializationException:无法延迟初始化 角色集合:com.testmany.entity.Role.userList,可以 不初始化代理 - 没有会话

在这里,我立即有一个问题 - 也许我没有正确添加用户并错误地为他分配角色?

如果我以另一种方式进行,例如:

            User user = new User("Иван");
             
            Role role = serviceJpa.findRoleByRoleName("ROLE_USER");

            user.addRole(role);
            serviceJpa.saveUser(user);

然后发生另一个异常:

<块引用>

消息 请求处理失败;嵌套异常是 org.springframework.dao.InvalidDataAccessApiUsageException: detached 传递给持久化的实体:com.testmany.shop.entity.Role;嵌套 异常是 org.hibernate.PersistentObjectException: detached entity 传递给持久化:com.testmany.entity.Role

我做错了什么?如何使用 FetchType.LAZY 添加用户,即没有 FetchType.EAGER。添加用户并为其分配角色的正确方法是什么?我究竟做错了什么。我已经查看并重新阅读了大量信息、休眠文档,但没有任何帮助。你好吗,显示?

2 个答案:

答案 0 :(得分:0)

在您的用户 model 中设置延迟提取如下:

City 1    The New York . City
dtype: object
City 1    False
dtype: bool

为了补偿延迟加载,请在您的 controller 中的某处初始化它,如下所示(只是为了给您提示):

@ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "app_user_role", joinColumns = @JoinColumn(name = "userid"), inverseJoinColumns = @JoinColumn(name = "roleid"))
    private List<Role> roles;

然后,在您的代码中的某处(例如 Service),将角色设置为用户,如下所示:

@ModelAttribute("roles")
    public List<Role> initializeRoles() {
        return (List<Role>) roleJPARepository.findAll();
    }

有关通过 UI 为用户设置/编辑角色的完整示例,请参见我的 GitHub 存储库 - https://github.com/ajkr195/springbootrocks

这与您要查找的内容非常接近。

答案 1 :(得分:0)

  @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "user_role",
            joinColumns = {@JoinColumn(name = "user_id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id")}
    )
private List<RoleUser> roleUserList;

你可以试试这个它可能会有帮助