Как разрешить LazyInitializationException в Spring данных покоя @RepositoryEventHandler @HandleAfterLinkSave? - PullRequest
4 голосов
/ 13 мая 2019

У меня есть приложение для восстановления данных пружины со связью между типами Match и Round

@Entity
public class Match {

    @OneToMany
    private List<Round> rounds;
    ...
}

Когда между матчем и раундом создается связь, например, вот так

curl -X PUT -d "http://localhost:8080/rounds/2" -H "Content-Type:text/uri-list" http://localhost:8080/matches/1/rounds;

я фиксирую это с помощью EventHandler, чтобы сделать некоторые обновления для моей модели домена:

public class MatchEventHandler

    @HandleAfterLinkSave
    public void handleLinkSave(Match match, List<Round> rounds) {
        ...
}

Мне нужно получить доступ ко второму аргументу, чтобы выполнить обновление, но это происходит, например, с rounds.get (0),возвращает

org.hibernate.LazyInitializationException: не удалось лениво инициализировать коллекцию, не удалось инициализировать прокси - нет Сеанс

Чтение других потоков о спящих режимах. LazyInitializationExceptions Я вижу в основном три подхода, которые предлагаются:

  1. Используйте Hibernate.initialize () - я не вижу, какой метод я мог бы вызвать, и это добавило бы некрасивую зависимость в инфраструктуру Hibernate
  2. Поместите метод контроллера в транзакцию - iпонять, что весенние данные уже все помещают в транзакцию.Кроме того, поскольку это приложение для восстановления данных весной, я не использую какой-либо контроллер или сервисный уровень, и поэтому я не буду знать, что именно вводить в транзакцию.
  3. Установите FetchType.EAGER для отношения - хотя на самом деле это не такправильное решение я попробовал.В этом случае второй аргумент метода @HandleAfterLinkSave представляет собой пустой список, поэтому он также не доставляет ожидаемый результат.

1 Ответ

1 голос
/ 01 июня 2019

Ссылки на свойства обрабатываются в следующем классе Spring:

org.springframework.data.rest.webmvc.RepositoryPropertyReferenceController

Хотя в большинстве случаев он работает довольно хорошо, он глючит здесь или там. Или, скажем так: у него есть несколько интересных вариантов поведения (последние месяцы я потратил месяцы на создание улучшенной версии Spring Data Rest ).

Если метод запроса был POST или PATCH, то второй параметр содержит обновленную коллекцию. Но если вы используете метод PUT, он содержит коллекцию original .

(Кроме того, нет способа решить, какая коллекция была изменена, если у вас есть несколько наборов свойств в вашей основной сущности. И есть эти сомнительные результаты для свойств типа карты, но это другая история. )

Так что лучшее решение ИМХО, если вы создадите метод репозитория в RoundRepository и используете его для перезагрузки коллекции:

@RestResource(exported = false)
List<Round> findAllByMatch(Match match);

Кстати! Что касается вашего варианта 2, прочитайте эту тему !

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...