Для более подробного описания вы можете прочитать мою статью Open Session In View Anti-Pattern . В противном случае, вот краткое изложение того, почему вам не следует использовать Open Session In View.
Open Session In View использует неправильный подход к извлечению данных. Вместо того, чтобы позволить бизнес-уровню решать, как лучше всего получить все ассоциации, необходимые для уровня представления, он заставляет контекст сохранения оставаться открытым, чтобы уровень представления мог запускать инициализацию прокси.

OpenSessionInViewFilterВызывает openSessionметод базового актива SessionFactoryи получает новый Session.
- Объект
Sessionпривязан к TransactionSynchronizationManager.
OpenSessionInViewFilterНазывает doFilterв качестве javax.servlet.FilterChainссылки объекта и запрос дополнительно обрабатывается
DispatcherServletНазывается, и он направляет запрос HTTP , чтобы лежащий в основе PostController.
- В
PostControllerзвонки на , PostServiceчтобы получить список Postсущностей.
PostServiceОткрывает новую транзакцию, и HibernateTransactionManagerповторно тот же , Sessionчто был открыт OpenSessionInViewFilter.
PostDAOПолучает список Postлиц без инициализации любой ленивой ассоциации.
- Объект
PostServiceфиксирует базовую транзакцию, но Sessionне закрывается, потому что он был открыт извне.
- В
DispatcherServletзапуске рендеринга интерфейса, который, в свою очередь, переходит ленивые ассоциации и вызывает их инициализации.
OpenSessionInViewFilterМожно закрыть Session, и лежащая в основе соединения с базой данных отпущена , а также.
На первый взгляд это может показаться не таким уж ужасным, но если взглянуть на это с точки зрения базы данных, ряд недостатков начинает становиться более очевидным.
Уровень сервиса открывает и закрывает транзакцию базы данных, но после этого явная транзакция не выполняется. По этой причине каждый дополнительный оператор, выпущенный на этапе визуализации пользовательского интерфейса, выполняется в режиме автоматической фиксации. Автоматическая фиксация оказывает давление на сервер базы данных, поскольку каждый оператор должен сбрасывать журнал транзакций на диск, что вызывает большой трафик ввода-вывода на стороне базы данных. Одна из оптимизаций заключается в том, чтобы пометить Connectionкак доступный только для чтения, что позволит серверу базы данных избежать записи в журнал транзакций.
Больше нет разделения проблем, потому что операторы генерируются как уровнем сервиса, так и процессом рендеринга пользовательского интерфейса. Написание интеграционных тестов, которые подтверждают количество сгенерированных операторов, требует прохождения всех уровней (веб, сервис, DAO) при развертывании приложения в веб-контейнере. Даже при использовании базы данных в памяти (например, HSQLDB) и легкого веб-сервера (например, Jetty) эти интеграционные тесты будут выполняться медленнее, чем если бы уровни были разделены, а тесты внутренней интеграции использовали базу данных, в то время как Внешние интеграционные тесты полностью имитировали уровень сервиса.
Уровень пользовательского интерфейса ограничен навигацией по ассоциациям, которые, в свою очередь, могут вызывать проблемы с запросами N + 1. Хотя Hibernate предлагает @BatchSizeвыборку ассоциаций в пакетах и FetchMode.SUBSELECTдля того, чтобы справиться с этим сценарием, аннотации влияют на план выборки по умолчанию, поэтому они применяются к каждому бизнес-варианту использования. По этой причине запрос уровня доступа к данным является гораздо более подходящим, поскольку он может быть адаптирован для требований текущего варианта использования к выборке данных.
И последнее, но не менее важное: соединение с базой данных может поддерживаться на протяжении фазы рендеринга пользовательского интерфейса (в зависимости от режима освобождения соединения), что увеличивает время аренды соединения и ограничивает общую пропускную способность транзакций из-за перегрузки в пуле соединений с базой данных. Чем дольше удерживается соединение, тем больше других одновременных запросов будут ждать, чтобы получить соединение из пула.
Таким образом, либо вы удерживаете соединение слишком долго, либо вы приобретаете / освобождаете несколько соединений для одного HTTP-запроса, тем самым оказывая давление на базовый пул соединений и ограничивая масштабируемость.
Весенний ботинок
К сожалению, в Spring Boot по умолчанию включен Open Session in View .
Итак, убедитесь, что в application.propertiesфайле конфигурации у вас есть следующая запись:
spring.jpa.open-in-view=false
Это отключит OSIV, чтобы вы могли справиться LazyInitializationExceptionправильно .