【问题标题】:Spring REST - cannot force H2 database to create keys manuallySpring REST - 无法强制 H2 数据库手动创建密钥
【发布时间】: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 建议如果没有 Employeeid,则使用请求路径中的 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 addEmployee{id=234, name='Samwise Gamgee', role='gardener'}
2021-08-17 15:53:34.956  INFO 34321 --- [nio-8080-exec-1] payroll.EmployeeController               : PUT: add Employee{id=3, name='Samwise Gamgee', role='gardener'}

我的问题是:是否有可能在 Employee 实体中启用手动 id 字段创建?如果可以,如何启用?

编辑: 确切地说,我想制定如下生成策略:

  1. 如果在新的Employee 中没有指定id,数据库应该使用某种自动生成策略来生成它——它也应该在任何可能的故障情况下发生,例如应用正在尝试使用 id 保存对象,该对象已在 db 中出现。
  2. 如果没有,请从新对象中获取 id

【问题讨论】:

    标签: java spring rest h2


    【解决方案1】:

    Employee 的属性 id 上的注释 @GeneratedValue 正在设置实体的 ID。您可以删除它并尝试一下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-30
      • 2020-08-12
      • 2019-01-12
      • 2019-07-25
      • 2018-04-28
      • 1970-01-01
      • 2018-08-10
      • 2014-12-30
      相关资源
      最近更新 更多