[英]How to add a JPA relationship to a subset list of attributes of a persisted Entity?
Having the following entities: 具有以下实体:
@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;
}
A Discipline
is for a specific Employee
. Discipline
是针对特定Employee
。 An Employee
may have 0 to several disciplines. Employee
可能有0到几个学科。 A discipline is for only one Employee
, no more no less. 一门学科只适用于一名Employee
,不多也不少。 In the Discipline
world (micro-service), it requires only a few attributes from the full Employee
class (id, firstName and lastName). 在Discipline
世界(微服务)中,它只需要完整Employee
类中的几个属性(id,firstName和lastName)。 In the Employee
World (micro-service), all Employee
fields are relevant. 在“ Employee
世界”(微服务)中,所有“ Employee
字段都是相关的。
How do I properly set my relation between both entities without fetching the Employee
entity for each Discipline
but only the required fields as I would do with a projection? 如何正确设置两个实体之间的关系,而又不像获取投影那样仅获取必填字段,而又不获取每个Discipline
的Employee
实体?
Must I refactor my Employee
entity by extracting a superclass with only the attributes' subset? 我是否必须通过提取仅包含属性子集的超类来重构Employee
实体?
In a magical world, I would like to have Discipline
entity defines as follow: 在一个神奇的世界中,我希望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();
}
Where EmployeeProfile
here should look similar to what a Spring Data JPA interface based projection would use. 这里的EmployeeProfile
应该看起来与基于Spring Data JPA接口的投影所使用的相似。
Aimed goals by doing this: 通过以下操作实现目标:
addDiscipline
request to fail due to an outdated employee instance on an irrelevant attribute. 实际上,我们不希望addDiscipline
请求由于无关属性上的雇员实例过时而失败。 This could happen if we link Discipline
to the full `Employee 如果我们将“ Discipline
”链接到完整的“雇员”,则可能会发生这种情况 Thanks to @crizzis who proposed what I was looking for. 感谢@crizzis提出了我想要的东西。 Here's the solution if anybody else is looking for this in future. 如果将来还有其他人在寻找,这就是解决方案。
SOLUTION: Simply have two entities, one with all the attributes and another one with only the subset you're interested in and have both entities using same table as follow: 解决方案:简单地有两个实体,一个具有所有属性,另一个具有仅您感兴趣的子集,并且两个实体都使用相同的表,如下所示:
@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;
}
Than you can have link other entities on this EmployeeProfile
class as follow: 比您可以在此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;
}
As by default on ManyToOne
relationship no operations are cascaded, this suits perfectly our needs. 默认情况下,在ManyToOne
关系中,没有操作会级联,因此非常适合我们的需求。
@AlanHay proposed to go down the REST way by having a REST endpoint returning this specific DTO. @AlanHay建议通过让REST端点返回此特定的DTO来实现REST方式。 It is another great solution especially in a micro-service architecture. 这是另一个很棒的解决方案,尤其是在微服务架构中。
As in our case, all our entities are still persisted in the same DB, we are going with the above solution as first step of doing micro-services is to build a great/decoupled monolithic application and because it will handle everything in only one DB query. 与我们的情况一样,我们所有的实体仍然保留在同一个数据库中,我们采用上述解决方案,因为进行微服务的第一步是构建一个伟大的/解耦的整体应用程序,因为它只能处理一个数据库中的所有内容查询。 And when the day come to split Discipline
and Employee
in different micro-services, it will be very simple to do so as Discipline table hold only the employee id, avoiding painful DB migration. 而且,当有一天将Discipline
和Employee
拆分为不同的微服务时,这样做非常简单,因为Discipline表仅保存了员工ID,从而避免了痛苦的数据库迁移。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.