由于重复键,使用CRUD存储库的现有子节点保存实体失败

时间:2015-12-15 20:50:51

标签: spring hibernate spring-boot spring-data-jpa one-to-many

User可以有多个Authorities。默认情况下,当我创建新用户时,我想添加他ROLE_USER权限。

这是用户实体:

@Entity
@Table(name = "Users")
public class User
{
    @Id    
    private String username;
    private String password;
    private String email;
    @OneToMany
    @JoinTable(
      name = "UserAuthority",
      joinColumns = @JoinColumn(name = "username"),
      inverseJoinColumns = @JoinColumn(name = "authority"))
    private List<Authority> authorities = new ArrayList<>();

和权威实体:

@Entity
public class Authority
{
    @Id
    private String authority;

我使用的基本UserRepositoryAuthorityReposiroty都延伸CrudRepository

这是注册新用户的方法:

public String register(User user)
{
    if (userRepository.findOne(user.getUsername()) != null)
    {
        return "User with given username already exists!";
    }
    user.setPassword(passwordEncoder.encode(user.getPassword()));
    user.getAuthorities().add(authRepository.findOne("ROLE_USER"));
    userRepository.save(user);
    return "User successfully registered!";
}

当我尝试注册新用户时,它失败并出现此错误:

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "uk_c1gaghspdr9qx2yt45moye10y"
  Detail: Key (authority)=(ROLE_USER) already exists.

我可以在日志中看到Hibernate试图插入ROLE_USER权限,这是不可能的,因为它已经存在,但我不明白为什么。我没有在@OneToMany注释上设置级联属性。

如何实现我的目标?

这是我的配置:

compile('org.springframework.boot:spring-boot-starter-data-jpa')
runtime('org.postgresql:postgresql:9.4-1206-jdbc42')

提前致谢!

1 个答案:

答案 0 :(得分:2)

问题在于关系。你有OneToMany - 意味着在其他网站上是关系ManyToOne ...如果您在一个用户中使用了某个权限,则不能将此实体(对象)用于其他用户。

您的问题的解决方案是在User类中更改与@ManyToMany insted @OneToMany的关系。它有点强大,但实际上它与ManyToMany有关系,因为用户可以拥有许多权限,并且许多用户都可以使用任何权限。