Ответ
Для использования составного (композитного) ключа в JPA необходимо создать отдельный класс-идентификатор и связать его с сущностью. Основной подход — аннотация @EmbeddedId.
Шаги настройки:
-
Создайте класс-идентификатор (
@Embeddable):import java.io.Serializable; import javax.persistence.Embeddable; @Embeddable public class ProjectAssignmentId implements Serializable { private Long projectId; private Long employeeId; // Обязательные: конструктор по умолчанию, equals(), hashCode() public ProjectAssignmentId() {} public ProjectAssignmentId(Long pId, Long eId) { this.projectId = pId; this.employeeId = eId; } // Геттеры, сеттеры, equals(), hashCode()... }- Класс должен быть
@Embeddable. - Должен реализовывать
Serializable. - Должен иметь корректные
equals()иhashCode()(используйте все поля ключа).
- Класс должен быть
-
Используйте его в сущности через
@EmbeddedId:import javax.persistence.*; @Entity public class ProjectAssignment { @EmbeddedId private ProjectAssignmentId id; // Сам составной ключ @ManyToOne @MapsId("projectId") // Связывает часть ключа с ассоциацией @JoinColumn(name = "project_id") private Project project; @ManyToOne @MapsId("employeeId") @JoinColumn(name = "employee_id") private Employee employee; private String role; // ... другие поля, конструктор, геттеры/сеттеры }
Альтернативный подход — @IdClass:
Менее удобен, требует дублирования полей ключа и в сущности, и в отдельном классе-идентификаторе. @EmbeddedId является более современным и объектно-ориентированным выбором.