Я видел spring.jpa.open-in-view=true
свойство в документации Spring Boot для конфигурации JPA.
- Является ли
true
это свойство значением по умолчанию, если оно вообще не задано ?; - Что это на самом деле делает? Я не нашел этому подходящего объяснения;
- Это заставляет вас использовать
SessionFactory
вместоEntityManagerFactory
? Если да, как я могу сказать, что я могу использовать егоEntityManagerFactory
вместо этого?
Спасибо!
java
spring
jpa
spring-boot
spring-data
Карлос Альберто
источник
источник
Антипаттерн OSIV
Вместо того, чтобы позволить бизнес-уровню решать, как лучше всего получить все ассоциации, необходимые для уровня представления, OSIV (открытый сеанс в представлении) заставляет контекст сохранения оставаться открытым, чтобы уровень представления мог запускать инициализацию прокси, как показано. по следующей диаграмме.
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
для того, чтобы справиться с этим сценарием, аннотации влияют на план выборки по умолчанию, поэтому они применяются к каждому бизнес-варианту использования. По этой причине запрос уровня доступа к данным является гораздо более подходящим, поскольку он может быть адаптирован к требованиям текущего варианта использования к выборке данных.И последнее, но не менее важное: соединение с базой данных поддерживается на всем этапе рендеринга пользовательского интерфейса, что увеличивает время аренды соединения и ограничивает общую пропускную способность транзакций из-за перегрузки в пуле соединений с базой данных. Чем дольше удерживается соединение, тем больше других одновременных запросов будут ждать, чтобы получить соединение из пула.
Весенняя загрузка и OSIV
К сожалению, OSIV (Open Session in View) включен по умолчанию в Spring Boot , и OSIV действительно плохая идея с точки зрения производительности и масштабируемости .
Итак, убедитесь, что в
application.properties
файле конфигурации у вас есть следующая запись:Это отключит OSIV, чтобы вы могли справиться
LazyInitializationException
правильно .Начиная с версии 2.0, Spring Boot выдает предупреждение, когда OSIV включен по умолчанию, поэтому вы можете обнаружить эту проблему задолго до того, как она повлияет на производственную систему.
Чтобы узнать больше об OSIV, прочтите эту статью .
источник