У меня ошибка StackOverflow при сохранении объекта с большой рекурсивной структурой в Spring Data / Hibernate.
Структура с рекурсией более или менее похожа на:
Schedule -> Contents -> Teachers -> Schedules
Класс расписания имеет:
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
public List<Content> getContents() {
...
}
Класс содержимого имеет:
@ManyToMany(cascade = CascadeType.ALL)
public List<Teacher> getTeachers() {
...
}
И учитель имеет:
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn (nullable = true)
public Schedule getSchedule() {
...
}
И для его сохранения я использую:
this.scheduleRepository.save(schedule);
Где this.scheduleRepository
является CrudRepository
.
При небольшом расписании оно сохраняется без проблем. Но когда это большой график (с большим количеством учителей, он генерирует исключение StackOverflow.
Я знаю, что это не бесконечная рекурсия, потому что она не рекурсирует, когда уже «проверила» элемент, и проблема в том, что у него так много элементов, что глубина слишком велика для стековой памяти.
Я также знаю, что могу увеличить объем стека с помощью -Xss4096k
, но я не знаю, насколько большими будут будущие расписания. Решение, которое я мог бы сделать, - это вручную сохранить отдельных лиц, а затем вручную глобальный объект (в основном, прервать рекурсию и сделать это вручную).
Однако, если Hibernate сохранил его в ширину, а не в глубину, он не будет использовать слишком много стековой памяти, поскольку будет только 3 уровня рекурсии. Но я не знаю, возможно ли это.
Итак, мой вопрос: возможно ли настроить Spring-data / JPA / Hibernate для сохранения всего каскада объектов в ширину, а не в глубину.