在简单 spring boot crud api 上创建用户时出现问题

Issue creating users on simple spring boot crud api

首次启动 api 后,前 3 个用户创建 Post 请求失败(post 底部的屏幕截图)并出现以下错误(唯一约束 vilocation)。

后续请求有效,第一个创建的用户的 ID 为 4,然后是 5,依此类推...

如何让用户创建在前 (3) 次尝试中起作用?

我怀疑这与我使用以下脚本进行的用户预播有关。可能自动 ID 生成首先尝试 1、2、3 -- 哪些已经在使用?

INSERT INTO user VALUES (1, 'user1', 'pass1', 'ADMIN'); INSERT INTO user VALUES (2, 'user2', 'pass2', 'USER'); INSERT INTO user VALUES (3, 'user3', 'pass3', 'ADMIN')

could not execute statement; SQL [n/a]; constraint [\"PRIMARY KEY ON PUBLIC.USER(ID)\"; SQL statement:\ninsert into user (name, password, role, id) values (?, ?, ?, ?) [23505-196]]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",

@RestController
public class UserResource {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users")
    public List<User> retrievaAllUsers() {
        return userRepository.findAll();
    }

    @DeleteMapping("/users/{id}")
    public void deleteUser(@PathVariable Long id) {
        userRepository.deleteById(id);
    }

    @PostMapping("/users")
    public ResponseEntity<Object> createUser(@RequestBody User user) {
        User savedUser = userRepository.save(user);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(savedUser.getId())
                .toUri();

        return ResponseEntity.created(location).build();

    }


}

-

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String password;
    @Enumerated(EnumType.STRING)
    private Role role;

    public User() {
        super();
    }

    public User(Long id, String name, String password, Role role) {
        this.id = id;
        this.name = name;
        this.password = password;
        this.role = role;
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Role getRole() {
        return role;
    }

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

如果您在列定义中使用 AUTO_INCREMENT,请尝试将策略从 GenerationType.AUTO 更改为 GenerationType.IDENTITY

当我将项目从 Spring Boot 1.5 升级到 2.0 时,我注意到了类似的行为。

只是一个假设。首先,您使用 sql 插入数据,但在您的代码中,您正在创建新用户并保存到数据库。因此,这个新创建的 id 为 1。但是您的数据库有一个用户记录,其主键为 1。请从 db 中删除所有值并从 rest 控制器创建您的记录。

在我看来,使用这样的序列,不要忘记在数据库中创建序列;

@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_generator")
@SequenceGenerator(name="user_generator", sequenceName = "user_seq", allocationSize=50)

或者阅读本文并选择要解决的问题。

  • AUTO:Hibernate根据所使用的来选择生成策略 方言,
  • IDENTITY:Hibernate 依赖于自动递增的数据库列来 生成主键,
  • SEQUENCE: Hibernate 从数据库中请求主键值 顺序,
  • TABLE: Hibernate使用数据库table模拟一个序列

PS:身份应该更相关但尝试其他人。

您还应该提供列名以确保它是有序的。

INSERT INTO 用户(ID、名称、密码、角色) 值 (1, 'user1', 'pass1', 'ADMIN');

INSERT INTO 用户(ID、名称、密码、角色) 值 (2, 'user2', 'pass2', 'USER');

INSERT INTO 用户(ID、名称、密码、角色) 值(3,'user3','pass3','ADMIN')