В JPA/Hibernate, стоит ли всегда определять Primary Key для Entity?

«В JPA/Hibernate, стоит ли всегда определять Primary Key для Entity?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, каждая JPA Entity должна иметь явно объявленный Primary Key (PK). Это не просто рекомендация, а обязательное требование спецификации JPA для корректной работы.

Причины:

  1. Требование JPA: Без @Id класс не считается Entity. Фреймворк нуждается в PK для однозначной идентификации экземпляра в контексте persistence, кэше первого уровня и при операциях merge()/update().
  2. Целостность данных: PK гарантирует уникальность записей на уровне базы данных.
  3. Производительность: В большинстве СУБД первичный ключ автоматически создает clustered или уникальный индекс, что значительно ускоряет поиск по ID и операции соединения (JOIN).

Стандартный подход (суррогатный ключ):

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // Автоинкремент в БД
    private Long id; // Суррогатный PK
    private String username;
    // ...
}

Альтернативы и исключения:

  • Естественный ключ (Natural Id): Можно использовать бизнес-поле (например, email) как PK, но это менее гибко при изменениях бизнес-правил. Чаще его помечают @NaturalId.
  • Составной ключ (@EmbeddedId или @IdClass): Используется для связующих таблиц @ManyToMany или когда уникальность определяется несколькими полями.
    @Entity
    public class Enrollment {
    @EmbeddedId
    private EnrollmentId id; // Класс, содержащий studentId и courseId
    // ...
    }

    Вывод: Всегда определяйте PK. Используйте суррогатный id по умолчанию, а естественный или составной ключ — только при явной необходимости.