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
. An Employee
may have 0 to several disciplines. A discipline is for only one Employee
, no more no less. In the Discipline
world (micro-service), it requires only a few attributes from the full Employee
class (id, firstName and lastName). In the Employee
World (micro-service), all Employee
fields are relevant.
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?
Must I refactor my Employee
entity by extracting a superclass with only the attributes' subset?
In a magical world, I would like to have Discipline
entity defines as follow:
@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.
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. This could happen if we linkDiscipline
to the full `Employee - 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.