在简单 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;
}
}
编辑 - 添加角色 class
public enum Role {
USER, ADMIN
}
如果您在列定义中使用 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')
首次启动 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;
}
}
编辑 - 添加角色 class
public enum Role { USER, ADMIN
}
如果您在列定义中使用 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')