首页 > 解决方案 > 如何使用映射表 user_role 在 Spring Boot 中使用多对多用户表仅将唯一值插入角色表

问题描述

用户实体:

        package com.user.authentication;
        
        import java.util.Collection;
        import java.util.HashSet;
        import java.util.Set;
        import java.util.stream.Collectors;
        
        import javax.persistence.CascadeType;
        import javax.persistence.Column;
        import javax.persistence.Entity;
        import javax.persistence.FetchType;
        import javax.persistence.GeneratedValue;
        import javax.persistence.GenerationType;
        import javax.persistence.Id;
        import javax.persistence.JoinColumn;
        import javax.persistence.JoinTable;
        import javax.persistence.ManyToMany;
        import javax.persistence.Table;
        import javax.persistence.UniqueConstraint;
        
        import com.user.authentication.RoleEntity;;
        
        @Entity
        @Table(name="users",uniqueConstraints = @UniqueConstraint(columnNames = "email"))
        
        public class UserEntity {
            
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            @Column(name = "USERID")
            private Long userId;
            
            @Column(name = "FIRSTNAME")
            private String firstName;
            
            @Column(name = "LASTNAME")
            private String lastName;
            
            @Column(name = "EMAIL")
            private String email;
            
            @Column(name = "PASSWORD")
            private String password;
        
            
            @ManyToMany(fetch = FetchType.LAZY,cascade = {CascadeType.PERSIST, CascadeType.MERGE})
            @JoinTable(
                name = "users_roles",
                joinColumns = @JoinColumn(
                    name = "USERID"),
                inverseJoinColumns = @JoinColumn(
                    name = "ROLEID"))
            
            private Set<RoleEntity> roles = new HashSet<RoleEntity>();
        
            public UserEntity() {}
        
            public UserEntity(String firstName, String lastName, String email, String password) {
                this.firstName = firstName;
                this.lastName = lastName;
                this.email = email;
                this.password = password;
            }
        
            public UserEntity(String firstName, String lastName, String email, String password, Collection < RoleEntity > roles) {
                this.firstName = firstName;
                this.lastName = lastName;
                this.email = email;
                this.password = password;
                this.roles = roles.stream().collect(Collectors.toSet());
                this.roles.forEach(x -> x.getUsers().add(this));
            }
        
            public Long getUserId() {
                return userId;
            }
        
            public void setUserId(Long userId) {
                this.userId = userId;
            }
        
            public String getFirstName() {
                return firstName;
            }
        
            public void setFirstName(String firstName) {
                this.firstName = firstName;
            }
        
            public String getLastName() {
                return lastName;
            }
        
            public void setLastName(String lastName) {
                this.lastName = lastName;
            }
        
            public String getEmail() {
                return email;
            }
        
            public void setEmail(String email) {
                this.email = email;
            }
        
            public String getPassword() {
                return password;
            }
        
            public void setPassword(String password) {
                this.password = password;
            }
        
            public Collection < RoleEntity > getRoles() {
                return roles;
            }
        
            public void setRoles(Collection<RoleEntity> roles) {
                this.roles = new HashSet<RoleEntity>(roles);
            }
        
            @Override
            public String toString() {
                return "User{" +
                    "userId=" + userId +
                    ", firstName='" + firstName + '\'' +
                    ", lastName='" + lastName + '\'' +
                    ", email='" + email + '\'' +
                    ", password='" + "*********" + '\'' +
                    ", roles=" + roles +
                    '}';
            }
        }
    

角色实体:

    package com.user.authentication;
    
    import java.util.Collection;
    import java.util.HashSet;
    import java.util.Set;
    
    import javax.persistence.CascadeType;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.FetchType;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.ManyToMany;
    import javax.persistence.Table;
    import javax.persistence.UniqueConstraint;
    
    import org.hibernate.engine.internal.CascadePoint;
    
    
    
    @Entity
    @Table(name = "roles",uniqueConstraints = @UniqueConstraint(columnNames = "name"))
    public class RoleEntity {
        
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "ROLEID")
        private Long roleId;
        
        @Column(name="NAME",unique = true, nullable = false)
        private String name;
        
       
        @ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY)
        private Set<UserEntity> users= new HashSet<UserEntity>();
        
    
        public RoleEntity() {}
    
        public RoleEntity(String name) {
            this.name = name;
        }
    
        public Long getRoleId() {
            return roleId;
        }
    
        public void setRoleId(Long id) {
            this.roleId = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
        
    
        public Collection<UserEntity> getUsers() {
            return users;
        }
    
        public void setUsers(Collection<UserEntity> users) {
            this.users = new HashSet<>(users);
        }
    
        @Override
        public String toString() {
            return "Role{" +
                "roleId=" + roleId +
                ", name='" + name + '\'' +
                ", users=" + users +
                '}';
        }
    }

我想创建具有许多角色的用户,并且应该能够按角色获取用户。我创建了 3 个表 1-user、1-role 和 3-user_role 一个映射表来保存用户到角色的映射。用户表有UserId,角色表有roleIduser_roleuserIdroleId。在角色表中,我的名称是唯一的。我使用了与用户和角色实体的多对多关系。当我尝试创建具有多个角色的用户并且创建具有与第一个用户相同的角色的另一个用户时,会出现 Nullpointer 异常。

org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException:唯一索引或主键违规:“PUBLIC.NAMEUNIQUE_INDEX_4 ON PUBLIC.ROLES(NAME) VALUES 1”;SQL 语句:插入角色 (roleid, name) 值 (null, ?) [23505-200]

我只想在角色不存在时将角色插入角色表中。

标签: spring-bootmany-to-manyhibernate-mapping

解决方案


推荐阅读