Зачем использовать тип Long для идентификатора сущности
Что проверяют
Понимаете ли вы, откуда берутся идентификаторы и чем грозит неудачный тип, а не только помните диапазон long. Следом обычно спрашивают, почему Long, а не long, и когда лучше взять UUID.
Как отвечать
Первый аргумент это диапазон. Integer ограничен 2 147 483 647, и на таблицах событий, логов или платежей это реально достижимо: вставка падает, а перевод колонки на BIGINT в большой живой таблице превращается в отдельный проект. Long даёт около 9,2 × 10^18 значений, запаса хватит. В базе ему соответствует BIGINT, в PostgreSQL обычно bigint generated always as identity или последовательность.
Второй аргумент касается обёртки и генерации:
nullзначит «ещё не сохранена»: Spring Data вisNew()проверяет id наnull, а для примитива на0, что хуже читается и путается с реальными значениями;- генерация:
GenerationType.SEQUENCEсallocationSize(по умолчанию 50) позволяет Hibernate выдавать id пачками и включать batch insert, а приIDENTITYпакетная вставка отключается, потому что id известен только послеINSERT.
Третий касается альтернатив:
- UUID: генерируется без базы, не раскрывает количество записей, удобен в распределённых системах. Минусы: 16 байт вместо 8, а случайный UUIDv4 фрагментирует B-tree индекс. UUIDv7 упорядочен по времени и эту проблему в основном снимает;
- строковые ключи: медленнее сравниваются и занимают больше места в каждом индексе, где встречаются.
Полезно упомянуть и фронтенд: JavaScript точно представляет целые только до 2^53, поэтому большие id вроде snowflake отдают в JSON строкой.
Где спотыкаются
Говорят, что Long «предотвращает коллизии». Уникальность обеспечивает генератор (последовательность, identity), а не тип поля.
Сравнивают идентификаторы через ==. Long кеширует значения от -128 до 127, поэтому в тестах с маленькими id сравнение работает, а на проде внезапно даёт false. Нужен equals() или Objects.equals().
Строят equals() и hashCode() на сгенерированном id. До persist он null, и сущность, положенная в HashSet до сохранения, после него в этом множестве «теряется».