Spring security spring安全删除用户失败

Spring security spring安全删除用户失败,spring-security,spring-data-jpa,spring-boot,Spring Security,Spring Data Jpa,Spring Boot,我正在使用SpringSecurity运行一个1.1.4.0版本的SpringBoot应用程序。我有基本的Spring用户和权限表和实体: @Entity @Table(name = "USERS") public class User implements UserDetails { @Id private String username; @Column(nullable = false) private String password; pri

我正在使用SpringSecurity运行一个1.1.4.0版本的SpringBoot应用程序。我有基本的Spring用户和权限表和实体:

@Entity
@Table(name = "USERS")
public class User implements UserDetails {

    @Id
    private String username;

    @Column(nullable = false)
    private String password;

    private boolean enabled;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private String companyName;

    @OneToMany(mappedBy = "username", fetch = FetchType.EAGER, orphanRemoval = true)
    @Cascade({org.hibernate.annotations.CascadeType.ALL})
    private Set<Authorities> roles = new HashSet<Authorities>();

/// getters and setters
}


@Entity
public class Authorities {

    @Id
    private String username;
    private String authority;
    /// getters and setters
}
当我尝试删除一个用户时,我得到一个错误:

org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint ["IX_AUTH_USERNAME: PUBLIC.AUTHORITIES FOREIGN KEY(USERNAME) REFERENCES PUBLIC.USERS(USERNAME) ('testUser')"; SQL statement:
delete from USERS where username=? [23503-172]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
我认为我的映射是错误的,但老实说,我不知道在哪里

更新: 基于良好的反馈,我现在有以下几点:

@Entity
@Table(name = "USERS")
public class User implements UserDetails {

    @Id
    private String username;

    @Column(nullable = false)
    private String password;

    private boolean enabled;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private String companyName;

    @ElementCollection(fetch=FetchType.EAGER)
    @CollectionTable(name="Authorities", joinColumns=@JoinColumn(name="username"))
    @Column(name="authority")
    private Set<String> roles = new HashSet<String>();

// getters & setters
}

@Repository
public interface UserRepository extends CrudRepository<User, String> {

    User findUserByUsername(String username);

    void delete(String username);

    List<User> findAll();
}

我正在使用H2,我在liquibase中创建和种子,如下所示:

<createTable tableName="Users">
    <column name="username" type="VARCHAR_IGNORECASE(50)"/>
    <column name="password" type="VARCHAR_IGNORECASE(500)"/>
    <column name="companyName" type="VARCHAR_IGNORECASE(500)"/>
    <column name="enabled" type="boolean"/>
    <column name="accountNonExpired" type="boolean"/>
    <column name="accountNonLocked" type="boolean"/>
    <column name="credentialsNonExpired" type="boolean"/>
</createTable>

<createTable tableName="Authorities">
    <column name="username" type="VARCHAR(50)">
        <constraints primaryKey="true" nullable="false"
                     foreignKeyName="ix_auth_username" references="Users(username)" deleteCascade="true"/>
    </column>
    <column name="authority" type="VARCHAR_IGNORECASE(500)"/>
</createTable>
删除这个类。请记住,实体与表不同。在用户类中使用以下映射:

@ElementCollectionfetch=FetchType.EAGER @CollectionTablename=权限,joinColumns=@JoinColumnname=用户名 @Columnname=权限 私人机构;
此外,您还可以在外键上添加DELETE CASCADE。

您是否尝试先删除用户的权限,然后再删除用户?是的,我也尝试过,但它会抛出referentialingtegrityexception或其他内容。要解决此问题,使用delete的实现更新问题以及如何创建表。我已使用当前代码状态更新了问题。有什么想法吗?我对liquibase不太了解,但你似乎把主键和外键弄混了。authority表的主键必须跨越用户名和权限。否则,一个用户只能有一个角色。我不确定是否遵循。如果我没有实体,我如何为用户保留权限,例如:boldAuthorities Authorities=newauthorities USER.getUsername,USER;user.getRoles.addauthorities;粗体如果我将权限添加为字符串,这些权限是否会被持久化?是的,当用户对象被持久化时,它们将被持久化。我需要做什么来删除用户的权限?我在上面提出了您的建议,并在username列中添加了一个deleteCascade=true的约束。但是当我删除一个用户时,我不认为权限也会被删除,因此我可以直观地验证记录。删除该用户时,权限表中的相关行应该自动删除。在外键就位的情况下,不要担心。如果我创建了一个用户,然后将其删除,并尝试重新创建相同的用户名,我会得到一个异常:boldcannotexecutestatement;SQL[n/a];约束[PUBLIC.AUTHORITIESUSERNAME上的主键A;SQL语句:插入到Authorities用户名中,权限值?,?[23505-172];嵌套异常为org.hibernate.exception.ConstraintViolationException:无法执行stateme bold,因此我认为权限表记录未被正确删除
@Entity
@Table(name = "USERS")
public class User implements UserDetails {

    @Id
    private String username;

    @Column(nullable = false)
    private String password;

    private boolean enabled;
    private boolean accountNonExpired;
    private boolean accountNonLocked;
    private boolean credentialsNonExpired;
    private String companyName;

    @ElementCollection(fetch=FetchType.EAGER)
    @CollectionTable(name="Authorities", joinColumns=@JoinColumn(name="username"))
    @Column(name="authority")
    private Set<String> roles = new HashSet<String>();

// getters & setters
}

@Repository
public interface UserRepository extends CrudRepository<User, String> {

    User findUserByUsername(String username);

    void delete(String username);

    List<User> findAll();
}
@Controller
@PreAuthorize("hasRole('Admin')")
@RequestMapping("/admin")
public class AdminController {

    @PreAuthorize("hasRole('ADMIN')")
    @Transactional
    @RequestMapping(value = "/deleteUser/{username}", method = RequestMethod.POST)
    public String deleteUser(@PathVariable String username, Model model) {
        customUserDetailsService.delete(username);
        updateModelWithAllUsers(model);
        model.addAttribute("user", new User());
        return "admin";
    }

    private void updateModelWithAllUsers(Model model) {
        model.addAttribute(USERLIST, customUserDetailsService.findAllUsers());
    }
..
}
@Component
public class CustomUserDetailsService implements UserDetailsService {
   public void delete(String username) {
        userRepository.delete(username);
    }
..
}
<createTable tableName="Users">
    <column name="username" type="VARCHAR_IGNORECASE(50)"/>
    <column name="password" type="VARCHAR_IGNORECASE(500)"/>
    <column name="companyName" type="VARCHAR_IGNORECASE(500)"/>
    <column name="enabled" type="boolean"/>
    <column name="accountNonExpired" type="boolean"/>
    <column name="accountNonLocked" type="boolean"/>
    <column name="credentialsNonExpired" type="boolean"/>
</createTable>

<createTable tableName="Authorities">
    <column name="username" type="VARCHAR(50)">
        <constraints primaryKey="true" nullable="false"
                     foreignKeyName="ix_auth_username" references="Users(username)" deleteCascade="true"/>
    </column>
    <column name="authority" type="VARCHAR_IGNORECASE(500)"/>
</createTable>
Caused by: org.h2.jdbc.JdbcSQLException: Unique index or primary key violation: "PRIMARY_KEY_A ON PUBLIC.AUTHORITIES(USERNAME)"; SQL statement:
insert into Authorities (username, authority) values (?, ?) [23505-172]