spring JPA用户,角色身份验证 - 如何避免重复的角色条目?

时间:2017-02-20 00:05:13

标签: spring jpa spring-boot spring-security

您好我刚开始使用JPA和Spring安全性,我花了一段时间尝试根据用户和角色进行身份验证。

用户应该能够拥有多个角色,角色可以属于许多用户。

应该只有大约4个角色。

我尝试使用@Manytomany映射和连接表来实现此目的。

它或多或少都有效,但是当我尝试使用一组角色来保持新用户时,它会向角色表添加重复的条目(或者如果我在角色表上放置一个唯一的密钥,则会触发英国违规)。

这是代码:

用户

 import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

@Entity
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    private String role;

    @ManyToMany(mappedBy = "roles",fetch = FetchType.LAZY)
    private Set<User> users;

    public Role(String role) {
        super();
        this.role = role;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public Set<User> getUsers() {
        return users;
    }

    public void setUser(Set<User> users) {
        this.users = users;
    }



}

作用

<VirtualHost *:80>
    ServerName mydomain.com
    ProxyPass / http://mail.domain.com:81
    ProxyPassReverse / http://mail.domain.com:81
    ProxyPassReverseCookieDomain mydomain.com mail.domain.com
</VirtualHost>

1 个答案:

答案 0 :(得分:1)

ManyToMany是正确的逻辑关系类型。您获得过多角色的原因可能是您创建了Role的新实例,但如果该角色已存在于数据库中,则必须将其加载到持久性上下文中,并且只有在不存在时才创建新角色。 / p>

如果您在代码中管理事务,如果您使用@Transactional的容器管理持久性,则应该删除事务代码和try-finally块。

try {
    List<String> roleNames = Lists.newArrayList("user, admin, superuser");
    User user = new User("Peter", "Pan");
    List<Role> roles = new ArrayList<>();
    entityManager.getTransaction().begin();
    for (String roleName : roleNames) {
        List<Role> found = entityManager.createQuery("select r from Roles r where r.name = :roleName", Role.class)
                .setParameter("roleName", roleName).getResultList();
        if (found.isEmpty()) {
            Role role = new Role(roleName);
            entityManager.persist(role);
            roles.add(role);
        } else {
            roles.addAll(found);
        }
    }
    user.setRoles(roles);
    entityManager.persist(user);
    entityManager.getTransaction().commit();
} finally {
    entityManager.close();
}

就我个人而言,我几乎从不使用JPA&#39; ManyToMany,我通常会将其分解为2 OneToMany个关系,这样我就有了映射表的实体,否则会被JPA神奇地创建。这也为您提供了额外的控制,例如,如果您需要修改或删除用户的角色,您可以直接删除UserRoleMapping实体,而不必操作Role和User上的列表。它还可以让您更好地控制级联。