Ответ
Скорее всего, возникнет ошибка LazyInitializationException, если связь загружается лениво (FetchType.LAZY).
Почему так происходит?
- Jackson пытается сериализовать все поля сущности, включая поле
@ManyToOne. - Для ленивой загрузки реальный объект подгружается через прокси при первом обращении к полю.
- Если к полю не обратились до закрытия сессии Hibernate (например, после выхода из метода сервиса с
@Transactional), то при попытке сериализации Jackson обратится к прокси, но сессия будет уже закрыта, что вызовет исключение.
Решение 1: Использовать @JsonIgnore (самое простое, если связь не нужна в JSON).
@Entity
public class Order {
@Id
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JsonIgnore // Исключаем поле из сериализации
private Customer customer;
// ... другие поля
}
Решение 2: Использовать DTO (Data Transfer Object) — лучшая практика.
@RestController
public class OrderController {
@GetMapping("/orders/{id}")
public OrderDto getOrder(@PathVariable Long id) {
Order order = orderService.findById(id);
// Маппинг сущности в DTO, где явно указаны нужные для API поля
return new OrderDto(order.getId(), order.getTotal());
}
}
Вывод: Прямая сериализация сущностей в контроллерах — антипаттерн. Используйте DTO или @JsonIgnore, чтобы контролировать выходные данные и избегать проблем с производительностью и инициализацией.