#spring-boot #debugging #recursion #one-to-many #many-to-one
#весенняя загрузка #отладка #рекурсия #один ко многим #многие к одному
Вопрос:
Я использую Spring Boot и Thymeleaf для создания веб-приложения.
Когда я отлаживаю свое приложение, оно работает очень МЕДЛЕННО. На каждом шаге F8 отладчик показывает сообщение «Сбор данных …» на моих объектах. И я долгое время не вижу состояния своих объектов (10-60 секунд).
Наконец, когда сбор данных завершен, я вижу StackOverflowError.
Я понимаю, что в этой ситуации происходит бесконечная рекурсия. Автомобильные ссылки на сервис, сервисные ссылки на автомобиль и так далее. И он переполняет toString()
метод для каждого объекта.
Я вижу много примеров использования @OneToMany
и @ManyToOne
аннотаций. Все они вызывают эту рекурсию и StackOverflowError. И в этом случае инженеры рекомендуют поставить @JsonIgnore
или @JsonManagedReference
/ @JsonBackReference
аннотации, чтобы исправить бесконечную рекурсию.
Эти советы отлично работают для сериализованного объекта REST API.
Проблема в том, что я не разрабатываю REST API. Я создаю веб-приложение MVC.
Итак, что вы можете порекомендовать мне, чтобы исправить эту рекурсию и иметь приложение для быстрой отладки?
Это плохой дизайн? Или что-то еще?
Спасибо
Ответ №1:
Я не испытываю таких проблем во время отладки, я думаю, что это больше связано с вашим дизайном. Однако попробуйте добавить LAZY, например:
@ManyToOne(fetch = FetchType.LAZY)
это может помочь.
Комментарии:
1. Ваш ответ полезен. Это частично помогло решить проблему с производительностью во время отладки. Спасибо
Ответ №2:
Рабочее решение проблемы:
-
Сначала нужно отметить
@ManyToOne(fetch = FetchType.LAZY)
аннотацию, чтобы повысить производительность при отладке. -
Второе, что нужно сделать, это изменить стандартный
toString
метод, созданный IDE. Для вложенных объектов вы должны возвращать не весь объект, а только идентификатор объекта.
Пример для Service
:
Перед модификацией:
@Override
public String toString() {
return "Service{"
"serviceId=" serviceId
", car=" car
", event='" event '''
", created=" created
", modified=" modified
'}';
}
После модификации:
@Override
public String toString() {
String carId;
if (car == null) {
carId = "null";
} else {
carId = car.getCarId().toString();
}
return "Service{"
"serviceId=" serviceId
", carId=" carId
", event='" event '''
", created=" created
", modified=" modified
'}';
}
Теперь я не получаю "Collecting data..."
сообщение отладчика и StackOverflowError
исключение.
Производительность отладки хорошая!