Кейс: StackOverflowError из-за Lombok @Data на связанных сущностях

Order и OrderItem связаны двусторонне: у Order список items, у OrderItem ссылка на order. Обе сущности помечены @Data. Логирование order.toString() падает со StackOverflowError.

Причина: сгенерированный toString() у Order вызывает toString() каждого OrderItem из списка, а тот вызывает toString() у своего order — и по кругу. То же самое с equals()/hashCode(), если они попадают в сравнение через коллекции. В юнит-тестах с одной сущностью без второй стороны связи это не всплывает — граф просто не загружен целиком.

@Entity @Data public class Order { @Id private Long id;

@OneToMany(mappedBy = "order") private List items; }

@Entity @Data public class OrderItem { @Id private Long id;

@ManyToOne private Order order; }

Исправление — точечно исключить обратную ссылку из toString/equals/hashCode:

@ToString.Exclude @EqualsAndHashCode.Exclude private Order order;

Спросят: почему это не поймали на code review раньше? Потому что StackOverflow ловит только сценарий, где реально загружен граф с обеих сторон — на одиночной сущности или с моками этого не происходит.

Lombok на JPA-сущностях с двусторонними связями почти всегда нужно точечно ограничивать полями, а не тянуть весь граф в equals/hashCode/toString.

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

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


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