Можно ли вставить сущность в таблицу без первичного ключа в Hibernate?

«Можно ли вставить сущность в таблицу без первичного ключа в Hibernate?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, можно, но это противоречит реляционной модели и не рекомендуется.

Почему это плохая практика:

  • Первичный ключ (@Id) гарантирует уникальность каждой строки.
  • Без него возможны дубликаты записей, что нарушает целостность данных.
  • Hibernate использует первичный ключ для идентификации объектов в кэше и управления их жизненным циклом (например, для merge или delete).

Пример сущности без @Id:

@Entity
@Table(name = "no_pk_table")
public class NoPkEntity {
    @Column(name = "data")
    private String data;
    // Отсутствует поле с аннотацией @Id
}

Важные нюансы:

  1. Поведение СУБД:
    • MySQL (InnoDB): автоматически создаст скрытый кластерный индекс, если явный первичный ключ не задан.
    • Oracle: не позволит создать таблицу без PRIMARY KEY или хотя бы одного столбца с ограничением NOT NULL.
  2. Работа с Hibernate: операции EntityManager.persist() могут завершиться успешно, но дальнейшая работа с такими сущностями (обновление, удаление) будет проблематичной, так как у них нет уникального идентификатора.