Какие аннотации Lombok ставили на entity
Что проверяют
Знаете ли вы, какие аннотации Lombok безопасны на JPA-сущности, а какие ломают работу с Hibernate. Вопрос с подвохом: ответ «ставил @Data» почти всегда ведёт к уточнению, что будет с equals, hashCode и toString на связях.
Как отвечать
Рабочий набор на сущности выглядит так:
@Getterи@Setter: основа. Сеттеры часто вешают точечно, чтобы не открывать изменениеidи служебных полей;@NoArgsConstructor(access = AccessLevel.PROTECTED): JPA требует конструктор без аргументов, а protected не даёт вызвать его из прикладного кода;@ToStringс@ToString.Excludeна ассоциациях: иначе обращение к ленивой коллекции вызовет лишний запрос илиLazyInitializationException, а двунаправленная связь уйдёт в бесконечную рекурсию;@EqualsAndHashCode(onlyExplicitlyIncluded = true)с@EqualsAndHashCode.Includeна натуральном ключе, либоequalsиhashCodeвручную поidс постояннымhashCode;@Builderв паре с@NoArgsConstructorи@AllArgsConstructor, а для полей с инициализатором@Builder.Default.
Почему @Data на сущности вреден: он генерирует equals и hashCode по всем полям. Сравнение трогает ленивые коллекции @OneToMany и загружает их, связи ходят по кругу, а при сгенерированном id хеш объекта меняется после persist, и сущность теряется в HashSet. @Value не подходит совсем: он делает класс и поля final, а Hibernate нужны изменяемые поля и возможность создать прокси-наследника.
Для DTO и проекций @Value или обычный record как раз уместны, это стоит проговорить.
Где спотыкаются
Ставят @Data и не могут объяснить, откуда в логах StackOverflowError. Причина в toString или hashCode двунаправленной связи.
Строят equals по сгенерированному id без учёта null: две новые сущности до сохранения оказываются равны.
Используют @Builder без @Builder.Default. Поле List<Item> items = new ArrayList<>() в собранном объекте окажется null, потому что билдер игнорирует инициализаторы полей.