Spring REST - 无法强制 H2 数据库手动创建密钥
Posted
技术标签:
【中文标题】Spring REST - 无法强制 H2 数据库手动创建密钥【英文标题】:Spring REST - cannot force H2 database to create keys manually 【发布时间】:2021-08-17 14:27:19 【问题描述】:我尝试使用 Spring Rest Tutorial 学习 Spring 的基础知识,但有一件事对我来说真的很有趣。
实体类:
@Entity
class Employee
private @Id @GeneratedValue Long id;
private String name;
private String role;
Employee()
Employee(String name, String role)
this.name = name;
this.role = role;
public Long getId()
return this.id;
public String getName()
return this.name;
public String getRole()
return this.role;
public void setId(Long id)
this.id = id;
public void setName(String name)
this.name = name;
public void setRole(String role)
this.role = role;
@Override
public boolean equals(Object o)
if (this == o)
return true;
if (!(o instanceof Employee))
return false;
Employee employee = (Employee) o;
return Objects.equals(this.id, employee.id) && Objects.equals(this.name, employee.name)
&& Objects.equals(this.role, employee.role);
@Override
public int hashCode()
return Objects.hash(this.id, this.name, this.role);
@Override
public String toString()
return "Employee" + "id=" + this.id + ", name='" + this.name + '\'' + ", role='" + this.role + '\'' + '';
我认为 EmployeeController 中的 replaceEmployee
方法有问题 - 有一段代码:
@PutMapping("/employees/id")
Employee replaceEmployee(@RequestBody Employee newEmployee, @PathVariable Long id)
return repository.findById(id)
.map(employee ->
employee.setName(newEmployee.getName());
employee.setRole(newEmployee.getRole());
return repository.save(employee);
)
.orElseGet(() ->
newEmployee.setId(id);
return repository.save(newEmployee);
);
Snippet 建议如果没有 Employee
和 id
,则使用请求路径中的 id
创建一个新员工。我已经对其进行了测试,似乎确实创建了 Employee ,但自动递增了id
。
修改代码:
@PutMapping("/employees/id")
Employee replaceEmployee(@RequestBody Employee newEmployee, @PathVariable Long id)
return repository.findById(id)
.map(employee ->
employee.setName(newEmployee.getName());
employee.setRole(newEmployee.getRole());
Employee result = repository.save(employee);
logger.info("PUT: Trying to replace + " + employee);
logger.info("PUT: replaced " + employee + " with " + result);
return result;
)
.orElseGet(() ->
newEmployee.setId(id);
Employee result = repository.save(newEmployee);
logger.info("PUT: Trying to add" + newEmployee);
logger.info("PUT: add " + result);
return result;
);
卷曲命令:
curl -X PUT localhost:8080/employees/234 -H 'Content-type:application/json' -d '"name": "Samwise Gamgee", "role": "gardener"'
结果:
"id":3,"name":"Samwise Gamgee","role":"gardener"
日志:
2021-08-17 15:53:34.956 INFO 34321 --- [nio-8080-exec-1] payroll.EmployeeController : PUT: Trying to addEmployeeid=234, name='Samwise Gamgee', role='gardener'
2021-08-17 15:53:34.956 INFO 34321 --- [nio-8080-exec-1] payroll.EmployeeController : PUT: add Employeeid=3, name='Samwise Gamgee', role='gardener'
我的问题是:是否有可能在 Employee
实体中启用手动 id
字段创建?如果可以,如何启用?
编辑: 确切地说,我想制定如下生成策略:
-
如果在新的
Employee
中没有指定id
,数据库应该使用某种自动生成策略来生成它——它也应该在任何可能的故障情况下发生,例如应用正在尝试使用 id
保存对象,该对象已在 db 中出现。
如果没有,请从新对象中获取 id
。
【问题讨论】:
【参考方案1】:Employee
的属性 id
上的注释 @GeneratedValue
正在设置实体的 ID。您可以删除它并尝试一下。
【讨论】:
以上是关于Spring REST - 无法强制 H2 数据库手动创建密钥的主要内容,如果未能解决你的问题,请参考以下文章
具有多个数据源 Oracle 和 H2 的 Spring Boot