gpt4 book ai didi

java - 如何将 JPA 关系添加到持久化实体的属性子集列表?

转载 作者:行者123 更新时间:2023-12-02 03:13:18 26 4
gpt4 key购买 nike

拥有以下实体:

@Entity
@Table
public class Employee {

@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

@NotBlank
private String firstName;

@NotBlank
private String lastName;

private Gender gender;
private Instant birthDate;
private String email;
private String corporateEmail;

@Embedded
private Address address;

// and many more
// + all getters and setters
}

@Entity
@Table
public class Discipline {

@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

@NotNull
private Instant date;
private String infraction;
}

纪律适用于特定的员工。一个 Employee 可能有 0 到多个纪律。纪律仅适用于一名员工,不多也不少。在Discipline 世界(微服务)中,它只需要完整Employee 类中的几个属性(id、firstName 和lastName)。在Employee世界(微服务)中,所有Employee字段都是相关的。

如何正确设置两个实体之间的关系,而不获取每个DisciplineEmployee实体,而只获取必填字段,就像我对投影所做的那样?

我必须通过提取仅包含属性子集的父类(super class)来重构我的 Employee 实体吗?

在魔法世界中,我希望 Discipline 实体定义如下:

@Entity
@Table
public class Discipline {

@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

@NotNull
private Instant date;
private String infraction;

@ManyToOne
private EmployeeProfile employeeProfile;
}

public interface EmployeeProfile {

UUID getId();
String getFirstName();
String getLastName();
}

此处的 EmployeeProfile 应该类似于基于 Spring Data JPA 接口(interface)的投影所使用的内容。

这样做的目标:

  • 避免在我们的实体进行版本化时出现问题。事实上,我们不希望 addDiscipline 请求由于不相关属性上的过时员工实例而失败。如果我们将 Discipline 链接到完整的“Employee”
  • ,就会发生这种情况
  • 通过减少数据库负载来提高性能(实体越细越好)
  • 尽可能减少实体之间的耦合。
  • 使实体和数据库设计尽可能简单。

最佳答案

感谢@crizzis 提出了我正在寻找的东西。如果其他人将来正在寻找这个解决方案,这里是解决方案。

解决方案:只需有两个实体,一个具有所有属性,另一个仅具有您感兴趣的子集,并且两个实体使用相同的表,如下所示:

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

@NotBlank
private String firstName;

@NotBlank
private String lastName;

private Gender gender;
private Instant birthDate;
private String email;
private String corporateEmail;

@Embedded
private Address address;

...
}

@Entity
@Table(name = "EMPLOYEE")
@Immutable
public class EmployeeProfile {

@Id
private UUID id;
private String firstName;
private String lastName;
}

您可以链接此 EmployeeProfile 类上的其他实体,如下所示:

@Entity
@Table
public class Discipline {

@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
private UUID id;

@NotNull
private Instant date;
private String infraction;

@ManyToOne
@JoinColumn(name = "employee_id")
private EmployeeProfile employeeProfile;
}

由于默认情况下,ManyToOne关系中没有任何操作级联,这完全适合我们的需求。

@AlanHay 建议通过让 REST 端点返回此特定 DTO 来采用 REST 方式。这是另一个很好的解决方案,尤其是在微服务架构中。

在我们的例子中,我们的所有实体仍然保留在同一个数据库中,我们将采用上述解决方案,因为执行微服务的第一步是构建一个出色/解耦的整体应用程序,因为它将处理中的所有内容只有一个数据库查询。当有一天将 DisciplineEmployee 拆分到不同的微服务中时,这样做将非常简单,因为 Discipline 表仅保存员工 ID,从而避免了痛苦的数据库迁移。

关于java - 如何将 JPA 关系添加到持久化实体的属性子集列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56978860/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com