简体   繁体   English

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

[英]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? 如何正确设置两个实体之间的关系,而又不像获取投影那样仅获取必填字段,而又不获取每个DisciplineEmployee实体?

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: 通过以下操作实现目标:

  • Avoid incoming issues when our entities will be versionned. 在对我们的实体进行版本控制时,避免出现传入问题。 In fact, we don't want an 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 ”链接到完整的“雇员”,则可能会发生这种情况
  • Improve performance by reducing load to our DB (slimmer entities the better) 通过减少数据库负载来提高性能(更细微的实体)
  • Reduce coupling between our entities as much as possible. 尽可能减少我们实体之间的耦合。
  • Keep entities and DB design as simple as possible. 使实体和数据库设计尽可能简单。

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. 而且,当有一天将DisciplineEmployee拆分为不同的微服务时,这样做非常简单,因为Discipline表仅保存了员工ID,从而避免了痛苦的数据库迁移。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从持久化实体 JPA 中删除列表的 object - removing an object of a list from a persisted entity JPA Spring JPA如何在子项在多对多关系中持久化时持久化父级 - Spring JPA how to persist parent when the child is persisted in ManyToMany relationship 是否可以使用带有 JPA 的 Spring MVC 仅更新实体上的属性子集? - Is it possible to update only a subset of attributes on an entity using Spring MVC with JPA? 如果我已经在数据库中有成千上万个相关实体,并且在集合中添加了新实体,那么在JPA中如何保持一对多关系 - How one to many relationship gets persisted in JPA if i have thousands of related entities already in data base and i add new entities in collection 如何使用enum与jpa作为持久化实体的数据成员? - how to use enum with jpa as a data member of persisted entity? 如何使用JPA获取最后一个持久化实体的Id - How to get Id of last persisted entity using JPA 如何知道已分离的JPA实体是否已被保留? - How to know if a detached JPA entity has already been persisted or not? 无法添加子实体 - JPA OneToMany 关系 - Unable to add child entity - JPA OneToMany relationship 扩展JPA实体以添加属性和逻辑 - Extend JPA entity to add attributes and logic JPA:如何将实体与关系属性相关联? - JPA: How to associate entities with relationship attributes?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM