Bu spring.jpa.open-in-view = Spring Boot'daki gerçek özellik nedir?


121

gördüm spring.jpa.open-in-view=trueJPA yapılandırması için Spring Boot belgelerinde özelliği .

  • true hepsi sağlanan değilse bu özellik için varsayılan değer ?;
  • Bu gerçekten ne yapıyor? Bunun için iyi bir açıklama bulamadım;
  • SessionFactoryBunun yerine seni kullanıyor EntityManagerFactorymu? Varsa, EntityManagerFactorybunun yerine kullanmama izin vermesini nasıl söyleyebilirim ?

Teşekkürler!

Yanıtlar:


52

Bu özellik , mevcut iş parçacığına OpenEntityManagerInViewInterceptorbir kaydeden bir anı kaydedecektir EntityManager, böylece EntityManagerweb isteği bitene kadar aynısına sahip olacaksınız . Hazırda Bekletme SessionFactoryvb. İle ilgisi yoktur .


Şu anda web isteği bitene kadar EntityManager'ı kontrol etmek için OpenEntityManagerInViewFilter filtresine sahibim. "OpenEntityManagerInViewInterceptor" demek istediğiniz bu durdurucu, "OpenEntityManagerInViewFilter" ile aynı mı? Aralarındaki fark nedir? Öyleyse, Spring Boot için sunucu uygulamamda bu filtreye sahip olmayacak mıyım?
Carlos Alberto

1
Durdurucu yalnızca DispatcherServlet'i İlkbaharda kullandığınızda çalışır (çünkü durdurucu bir Yay mekanizmasıdır). Filtre, yapılandırılmış tüm sunucu uygulamalarına eşlenebilir (bunu, uygulamalarımızdan birinde FacesServlet için kullanıyoruz). Dolayısıyla, yalnızca DispatcherServlet'i kullanıyorsanız, özelliği ekleyebilir ve filtreyi kaldırabilirsiniz, aksi takdirde filtreyi kullanabilirsiniz.
dunni

300

OSIV Anti-Pattern

Görünüm katmanının ihtiyaç duyduğu tüm ilişkilendirmeleri en iyi nasıl getireceğine iş katmanının karar vermesine izin vermek yerine, OSIV (Görünümde Açık Oturum) Kalıcı Bağlamı açık kalmaya zorlar, böylece Görünüm katmanı Proxy başlatmayı tetikleyebilir. aşağıdaki diyagram ile.

görüntü açıklamasını buraya girin

  • OpenSessionInViewFilterAramaları openSessiontemel yöntemi SessionFactoryve yeni elde Session.
  • SessionBağlıdır TransactionSynchronizationManager.
  • OpenSessionInViewFilterAramaları doFilterbir javax.servlet.FilterChainamacı, referans ve daha ayrıntılı işlenir
  • DispatcherServletDenir ve altta yatan için bu yolları HTTP isteği olduğunu PostController.
  • PostControllerÇağrılar PostServicelistesini almak için Postkişiler.
  • PostServiceYeni bir işlem açar ve HibernateTransactionManageraynı yeniden kullanır Sessiontarafından açıldığını OpenSessionInViewFilter.
  • PostDAOListesini getirir Postherhangi tembel ilişki başlatılıyor dışındaki varlıklar.
  • PostServiceAltında yatan işlem taahhüt, ama Sessiono dışarıdan açıldı çünkü kapalı değil.
  • Başlangıçlar DispatcherServlet, sırayla tembel ilişkilendirmelerde gezinen ve başlatılmalarını tetikleyen kullanıcı arayüzünü oluşturmaya başlar.
  • OpenSessionInViewFilterKapatabilir Sessionve altta yatan veritabanı bağlantısı sıra serbest bırakılır.

İlk bakışta, bu yapılacak çok kötü bir şey gibi görünmeyebilir, ancak bir veritabanı perspektifinden baktığınızda, bir dizi kusur daha belirgin hale gelmeye başlar.

Hizmet katmanı bir veritabanı işlemini açar ve kapatır, ancak daha sonra devam eden açık bir işlem yoktur. Bu nedenle, kullanıcı arabirimi oluşturma aşamasından yayınlanan her ek ifade, otomatik kesinleştirme modunda yürütülür. Otomatik kesinleştirme, veritabanı sunucusuna baskı uygular, çünkü her bir ifade işlem günlüğünü diske aktarmalıdır, bu nedenle veritabanı tarafında çok fazla G / Ç trafiğine neden olur. Optimizasyonlardan biri Connection, veritabanı sunucusunun işlem günlüğüne yazmaktan kaçınmasına izin verecek şekilde salt okunur olarak işaretlemek olacaktır.

Artık endişelerin ayrılması yok çünkü ifadeler hem hizmet katmanı hem de UI oluşturma işlemi tarafından üretiliyor. Üretilen ifadelerin sayısını belirten entegrasyon testleri yazmak , uygulamayı bir web kapsayıcısına yerleştirirken tüm katmanlardan (web, hizmet, DAO) geçmeyi gerektirir. Bir bellek içi veritabanı (ör. HSQLDB) ve hafif bir web sunucusu (ör. Jetty) kullanıldığında bile, bu entegrasyon testlerinin yürütülmesi, katmanların ayrılmasına ve arka uç entegrasyon testlerinin veritabanını kullanmasına göre daha yavaş olacaktır. ön uç entegrasyon testleri, hizmet katmanını tamamen alay ediyordu.

UI katmanı, sırayla N + 1 sorgu problemlerini tetikleyebilecek gezinme ilişkileri ile sınırlıdır . Hibernate, @BatchSizeilişkilendirmeleri toplu olarak FetchMode.SUBSELECTgetirmeyi ve bu senaryoyla başa çıkmayı teklif etse de , ek açıklamalar varsayılan getirme planını etkilediğinden, her iş kullanım durumuna uygulanır. Bu nedenle, bir veri erişim katmanı sorgusu çok daha uygundur çünkü mevcut kullanım durumu veri getirme gereksinimlerine göre uyarlanabilir.

Son olarak, veritabanı bağlantısı, UI oluşturma aşaması boyunca tutulur, bu da bağlantı kiralama süresini artırır ve veritabanı bağlantı havuzundaki tıkanıklık nedeniyle toplam işlem hacmini sınırlar. Bağlantı ne kadar tutulursa, havuzdan bağlantı almak için eşzamanlı talepler o kadar fazla bekleyecektir.

Spring Boot ve OSIV

Maalesef OSIV (Görünümde Açık Oturum), Spring Boot'ta varsayılan olarak etkindir ve OSIV, performans ve ölçeklenebilirlik açısından gerçekten kötü bir fikirdir .

Bu nedenle, application.propertiesyapılandırma dosyasında aşağıdaki girişe sahip olduğunuzdan emin olun :

spring.jpa.open-in-view=false

Bu, OSIV'i devre dışı bırakacak ve böylece doğru şekilde idareLazyInitializationException edebileceksiniz .

Sürüm 2.0'dan başlayarak, Spring Boot , OSIV varsayılan olarak etkinleştirildiğinde bir uyarı verir , böylece bu sorunu bir üretim sistemini etkilemeden çok önce keşfedebilirsiniz.

OSIV hakkında daha fazla ayrıntı için bu makaleye göz atın .


14
Bugünlerde kaydedilen bir UYARI var.
Vlad Mihalcea

Bu genel olarak Spring için mi yoksa yalnızca Spring Boot için mi geçerli? Bu, bir özellik ayarlamak yerine @ Configuration-açıklamalı bir sınıf aracılığıyla devre dışı bırakılabilir mi?
Gordon

2
Yalnızca Spring Boot için geçerlidir. Standart İlkbaharda, hangi fasulyeleri kullanacağınızı veya OSIV gibi bir web Filtresi isteyip istemediğinizi açıkça seçersiniz. Bazı ek açıklamalarla devre dışı bırakabilir misin bilmiyorum. Yalnızca yapılandırma ayarını biliyorum.
Vlad Mihalcea

Bu bir anti-model değil. Bazen olumsuz, çoğu zaman oldukça nötr ve birçok durumda olumlu bir şekilde performans etkileri vardır: gerçekten tembel bir ilişkiyle başlamak istiyorsanız, her durumda sorguyu yapmanız gerekmez. ve gerektiğinde açık görünüm kullanarak bunu önleyebilir.
ymajoros

5
Wikipedia'ya göre, "Bir anti-model, genellikle etkisiz olan ve oldukça ters etki yaratma riski olan, tekrar eden bir soruna verilen yaygın bir tepkidir". Görünümdeki Açık Oturum tam olarak budur.
Vlad Mihalcea
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.