Кейс: двусторонняя связь сущностей ушла в StackOverflowError через Jackson

Order хранил List через @OneToMany, каждый OrderItem — обратную ссылку на Order через @ManyToOne. Связь завели для удобства навигации по графу в коде сервиса, без единой аннотации Jackson по обе стороны.

Контроллер возвращал Order напрямую из репозитория. Jackson сериализовал order, дошёл до items, каждый item сериализовал своё поле order, которое снова тащило items — рекурсия без выхода до StackOverflowError. В юнит-тестах сервисного слоя это не всплывало: там сущности собирали вручную и никогда не сериализовали в JSON.

public class Order { @JsonManagedReference private List items; }

public class OrderItem { @JsonBackReference private Order order; }

Спросят следом: почему это не единственная проблема такого кода. Возврат Entity из контроллера тащит в JSON ленивые прокси Hibernate и поля, которые не должны попадать во внешний контракт, и завязывает API на структуру таблиц. Цикл сериализации — самый заметный симптом, а не корень проблемы.

Правильный фикс не в аннотациях на entity, а в DTO на границе контроллера — цикл там просто не возникает.

Тренажёр: 600 вопросов, мок с таймером, план повторов

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки