У меня есть следующая модель класса:
Я реализовал это следующим образом:
Проект:
@Data
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToMany
@JsonIgnore
@JoinTable(
name = "employee_projects",
joinColumns = @JoinColumn(name = "project_id"),
inverseJoinColumns = @JoinColumn(name = "employee_id")
)
private List<Employee> employees;
@OneToMany(mappedBy = "project", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Role> roles;
// more fields
}
Сотрудник:
@Data
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToMany
@JsonIgnore
@JoinTable(
name = "employee_projects",
joinColumns = @JoinColumn(name = "employee_id"),
inverseJoinColumns = @JoinColumn(name = "project_id")
)
private List<Project> projects;
@ManyToMany
@JsonIgnore
@JoinTable(
name = "employee_roles",
joinColumns = @JoinColumn(name = "employee_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private List<Role> roles;
// more fields
}
Роль:
public class Role {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne
@JsonIgnore
@NotNull
private Project project;
@ManyToMany
@JsonIgnore
@JoinTable(
name = "employee_roles",
joinColumns = @JoinColumn(name = "role_id"),
inverseJoinColumns = @JoinColumn(name = "employee_id")
private List<Employee> employees;
// more fields
)
}
Таким образом, каждый проект имеет несколько сотрудников и ролей. В моем приложении я могу добавить сотрудника с ролью в проект. Так что они всегда пара. Сотрудник в проекте всегда играет одну роль. Я контролирую это в businesslogi c.
Вопрос: Учитывая проект, возможно ли найти всех его сотрудников, связать каждого сотрудника с его ролью в этом проекте (вот роль, которая связана как с сотрудником, так и с данным проектом, я удостоверяюсь, что всегда есть только одна роль, которая выполняет это условие) в одном запросе?
Так что вызов findEmployeeWithRole(project)
должен вернуть список этого класса который содержит всех сотрудников проекта с их связанной ролью для этого проекта:
public class EmployeeAndRole {
private Employee employee;
private Role role;
}
В настоящее время я могу достичь этого только в n + 1 запросах:
Один запрос, чтобы найти всех сотрудников проекта:
@Query("SELECT project.employees FROM Project project WHERE project.id = :id")
List<Employee> findByProjectId(@Param("id") long id)
И затем n запросов (для каждого сотрудника в списке), чтобы найти роль, с которой сотрудник связан в этом проекте:
@Query("SELECT role FROM Role role WHERE role.project.id = :projectId AND :employeeId IN (SELECT employees.id FROM role.employees employees)
Role findByProjectIdAndEmployeeId(@Param("projectId") long projectId, @Param("employeeId") long employeeId)
Могу ли я достичь это в одном запросе? Если нет, каковы другие мои варианты, я должен попытаться переделать мою диаграмму класса?