Почему в Hibernate важно корректно указывать идентификатор первичного ключа и какие проблемы могут возникнуть при ошибках
Что проверяют
Понимаете ли вы, что идентификатор в Hibernate это не просто колонка, а ключ, по которому живёт персистентный контекст. Вопрос вытаскивает опыт: кто ловил дубликаты в множестве и отключившийся батчинг, отвечает конкретикой.
Как отвечать
Сначала сказать, зачем идентификатор нужен именно ORM. Персистентный контекст, он же кэш первого уровня, адресует сущности парой «тип плюс идентификатор». По ней он гарантирует, что в рамках сессии одной строке соответствует один объект, по ней же выстраивает грязную проверку и порядок операций при сбросе.
Дальше про выбор стратегии:
IDENTITYтребует выполнить вставку, чтобы узнать ключ, поэтому Hibernate не может отложитьINSERT, и батчинг вставок перестаёт работать;SEQUENCEотдаёт значения заранее, батчинг живёт, а пулящий оптимизатор сокращает число обращений к последовательности;- натуральный ключ вроде почты или артикула выглядит удобно ровно до того дня, когда бизнес решит, что его можно поменять.
Отдельный блок про equals и hashCode. Если они считаются по сгенерированному идентификатору, у новой сущности он пустой; объект кладут в HashSet, после сброса идентификатор появляется, хеш меняется, и объект теряется в собственном множестве. Рабочие варианты: бизнес-ключ или заранее присвоенный UUID.
Где спотыкаются
Путают persist и merge для отсоединённой сущности. Объект с заполненным идентификатором, приехавший из формы, для новой сессии не является управляемым: persist на нём падает, а merge тихо подтянет строку и перезапишет её полями пришедшего объекта, включая пустые.
Второе: объявляют идентификатор примитивом. У long нет состояния «ключа ещё нет», ноль воспринимается как настоящее значение, и Hibernate ошибается, решая, новая перед ним сущность или отсоединённая.
Третье: делают составной ключ там, где хватило бы суррогатного. @EmbeddedId тянет за собой корректные equals и hashCode на классе ключа, усложняет связи и превращает каждое обращение по ключу в многословную конструкцию.