java - 如何设计实体以存储预定义字段

标签 java hibernate

假设我成功创建了一个数据库表和相应的java实体。该实体代表 worker 可能担任的职位。作为主键,它使用递增的 ID 号而不是业务键:

@Entity
public class Position {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

private String positionName;

private String description;

// getters and setters

}

假设该公司有三个职位:

id: 1 positionName: "Teacher"  description: "To be edited"
id: 2 positionName: "Janitor"  description: "To be edited"
id: 3 positionName: "Chairman" description: "To be edited"

现在我们有一个 Employee 实体类:

@Entity
public class Employee {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

private String name;

private String surname;

// HERE THE PROBLEMATIC RELATION
@OneToOne(fetch = FetchType.EAGER) 
@JoinColumn(name = "positionId") 
public Position position;

// getters and setters

}

正如您可能认为的,Employee 实体的这种设计会导致问题。 当使用 Spring 以 JSON 格式为新员工进行 POSTing 时,我发送以下数据以保留具有教师职位的新员工 Ellen Johansson:

 {
   "name" : "Ellen",
   "surname" : "Johansson",
   "position" : {
    "id" : 1
    }
 }

正如您可能猜测的那样,此 POSTing 会覆盖 id = 1 的现有位置,并且由于positionName 和positionDesription 均为空,我最终得到编辑后的位置表,如下所示:

id: 1 positionName: null  description: null
id: 2 positionName: "Janitor"  description: "To be edited"
id: 3 positionName: "Chairman" description: "To be edited"

如何设计我的员工职位关系,以便:

在持久化新员工时声明职位 ID 就足够了,但这不会覆盖预定义职位表中的现有行,并且如果职位表中不存在职位 id 描述的行,也不会添加新行?

*我猜 OneToOne 关系正在使一切崩溃,我应该使用一些 @Embedded 关系。

最佳答案

首先,它可能应该是ManyToOne:通常有多个员工从事相同的工作。

第二:你混合了三个完全不同的方面:

  1. 应如何设计持久性模型,
  2. 应如何设计您的 HTTP API,
  3. 如何将员工分配到现有职位

关于第一点,除了 OneToOne 应该是 ManyToOne 之外,您已经了解了。

关于第二点:您不想接受在 API 中担任职位的员工。您想要接受创建 Employee 所需的数据(可以等于、小于或大于 Employee 实体包含的数据),以及了解其位置所需的数据,即职位的 ID。因此,不要使用持久性 JPA 实体来表示 API 的输入。使用专用的 EmployeeCreationCommand 类,其中包含客户端应发送的内容(不多不少),以便创建员工:姓名、职位 ID。

关于第三点:现在您收到了要创建的员工的信息,包括其职位的ID,您需要

  • 获取由接收到的位置 ID 标识的 Position 实体
  • 创建一个 Employee 实例,其中填充了命令中收到的信息,并链接到您在上一步中获得的 Position 实例
  • 留住该员工

关于java - 如何设计实体以存储预定义字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57622441/

相关文章:

java - org.hibernate.tuple.AbstractEntityTuplizer.createProxy 中的空指针异常

java - Spring 数据 JPA : Batch insert for nested entities

java - 如何使用一组中的键和另一组中的值填充 HashMap

java - 查询我的 JPA 提供程序 (Hibernate) 以获取实体的 <Id,Name> 集合

java - 如何使用 java 中的日期 API 验证年份

java - 使用hibernate和java进行Mysql查询时出错

hibernate - 无法使用 JPA EntityManager

java - hibernate : How to Join 3 tables in one join table by Annotation?

Java,是否可能 - 自动方法范围跟踪,如 C++ 中的宏

java - 如何从Java中的字符串中提取部分?