Saya melihat spring.jpa.open-in-view=true
properti dalam dokumentasi Spring Boot untuk konfigurasi JPA.
- Apakah nilai
true
default untuk properti ini jika tidak disediakan sama sekali ?; - Apa yang sebenarnya dilakukan ini? Saya tidak menemukan penjelasan yang baik untuk itu;
- Apakah itu membuat Anda menggunakan,
SessionFactory
bukanEntityManagerFactory
? Jika ya, bagaimana saya bisa mengatakannya untuk mengizinkan saya menggunakanEntityManagerFactory
?
Terima kasih!
java
spring
jpa
spring-boot
spring-data
Carlos Alberto
sumber
sumber
Anti-Pola OSIV
Alih-alih membiarkan lapisan bisnis memutuskan cara terbaik untuk mengambil semua pengaitan yang diperlukan oleh lapisan Tampilan, OSIV (Sesi Terbuka dalam Tampilan) memaksa Konteks Persistensi untuk tetap terbuka sehingga lapisan Tampilan dapat memicu inisialisasi Proxy, seperti yang diilustrasikan dengan diagram berikut.
OpenSessionInViewFilter
menyebutopenSession
metode yang mendasariSessionFactory
dan memperoleh baruSession
.Session
terikat keTransactionSynchronizationManager
.OpenSessionInViewFilter
menyebutdoFilter
darijavax.servlet.FilterChain
referensi objek dan permintaan itu diproses lebih lanjutDispatcherServlet
disebut, dan rute permintaan HTTP ke mendasariPostController
.PostController
panggilanPostService
untuk mendapatkan daftarPost
entitas.PostService
membuka transaksi baru, danHibernateTransactionManager
menggunakan kembali samaSession
yang dibuka olehOpenSessionInViewFilter
.PostDAO
menjemput daftarPost
entitas tanpa menginisialisasi setiap asosiasi malas.PostService
melakukan transaksi yang mendasarinya, tetapiSession
tidak tertutup karena dibuka secara eksternal.DispatcherServlet
dimulai rendering UI, yang, pada gilirannya, menavigasi asosiasi malas dan memicu inisialisasi mereka.OpenSessionInViewFilter
dapat menutupSession
, dan koneksi database yang mendasari dilepaskan juga.Pada pandangan pertama, ini mungkin tidak terlihat seperti hal yang buruk untuk dilakukan, tetapi, setelah Anda melihatnya dari perspektif database, serangkaian kekurangan mulai menjadi lebih jelas.
Lapisan layanan membuka dan menutup transaksi database, tetapi setelah itu, tidak ada transaksi eksplisit yang terjadi. Karena alasan ini, setiap pernyataan tambahan yang dikeluarkan dari fase rendering UI dijalankan dalam mode komit otomatis. Komitmen otomatis memberi tekanan pada server database karena setiap pernyataan harus membuang log transaksi ke disk, sehingga menyebabkan banyak lalu lintas I / O di sisi database. Salah satu pengoptimalan akan menandai
Connection
sebagai read-only yang akan memungkinkan server database untuk menghindari penulisan ke log transaksi.Tidak ada lagi pemisahan masalah karena pernyataan dibuat oleh lapisan layanan dan proses rendering UI. Menulis pengujian integrasi yang menegaskan jumlah pernyataan yang dihasilkan melalui semua lapisan (web, layanan, DAO) saat aplikasi diterapkan di wadah web. Bahkan ketika menggunakan database dalam memori (misalnya HSQLDB) dan web server ringan (misalnya Jetty), pengujian integrasi ini akan lebih lambat untuk dijalankan daripada jika lapisan dipisahkan dan pengujian integrasi back-end menggunakan database, sedangkan pengujian integrasi pengujian integrasi front-end mengejek lapisan layanan sama sekali.
Lapisan UI terbatas untuk menavigasi asosiasi yang pada gilirannya dapat memicu masalah kueri N + 1 . Meskipun Hibernate menawarkan
@BatchSize
untuk mengambil pengaitan dalam kelompok, danFetchMode.SUBSELECT
untuk mengatasi skenario ini, anotasi memengaruhi rencana pengambilan default, sehingga diterapkan ke setiap kasus penggunaan bisnis. Untuk alasan ini, kueri lapisan akses data jauh lebih cocok karena dapat disesuaikan dengan persyaratan pengambilan data kasus penggunaan saat ini.Last but not least, koneksi database diadakan sepanjang fase rendering UI yang meningkatkan waktu sewa koneksi dan membatasi throughput transaksi secara keseluruhan karena kemacetan di pool koneksi database. Semakin banyak koneksi ditahan, semakin banyak permintaan bersamaan lainnya yang akan menunggu untuk mendapatkan koneksi dari pool.
Spring Boot dan OSIV
Sayangnya, OSIV (Sesi Terbuka dalam Tampilan) diaktifkan secara default di Spring Boot , dan OSIV benar - benar ide yang buruk dari perspektif kinerja dan skalabilitas .
Jadi, pastikan bahwa di
application.properties
file konfigurasi, Anda memiliki entri berikut:Ini akan menonaktifkan OSIV sehingga Anda dapat menangani dengan
LazyInitializationException
cara yang benar .Dimulai dengan versi 2.0, Spring Boot mengeluarkan peringatan ketika OSIV diaktifkan secara default, sehingga Anda dapat menemukan masalah ini jauh sebelum itu mempengaruhi sistem produksi.
Untuk detail lebih lanjut tentang OSIV, lihat artikel ini .
sumber