Jawaban:
Pembilasan sesi memaksa Hibernate untuk menyinkronkan status dalam memori Session
dengan database (yaitu untuk menulis perubahan ke database). Secara default, Hibernate akan menghapus perubahan secara otomatis untuk Anda:
Mengizinkan untuk secara eksplisit membersihkan Session
memberikan kontrol yang lebih baik yang mungkin diperlukan dalam beberapa situasi (untuk mendapatkan ID yang ditetapkan, untuk mengontrol ukuran Sesi, ...).
id = session.save(obj);
dan transaksi dilakukan di baris berikutnya tetapi obj tidak diselamatkan ke DB, Mengapa? 2) Saya menyimpan obj menggunakan session.save(obj);
dengan komit dan saat kembali saya digunakan return obj.getprimaryID();
Dalam hal ini obj disimpan ke DB. Jadi mengapa perilaku ini terjadi?
Seperti yang dikatakan dengan benar dalam jawaban di atas, dengan menelepon flush()
kami memaksa hibernate untuk menjalankan perintah SQL pada Database. Tapi pahamilah bahwa perubahan belum "dilakukan". Jadi setelah melakukan flush dan sebelum melakukan commit, jika Anda mengakses DB secara langsung (katakanlah dari SQL prompt) dan memeriksa baris yang dimodifikasi, Anda TIDAK akan melihat perubahannya.
Ini sama dengan membuka 2 sesi perintah SQL. Dan perubahan yang dilakukan dalam 1 sesi tidak terlihat oleh orang lain hingga dilakukan.
Saya hanya tahu bahwa ketika kami memanggil session.flush()
pernyataan kami dieksekusi dalam database tetapi tidak berkomitmen.
Misalkan kita tidak memanggil flush()
metode pada objek sesi dan jika kita memanggil metode komit maka secara internal akan melakukan pekerjaan mengeksekusi pernyataan pada database dan kemudian melakukan.
commit=flush+commit
(dalam hal fungsionalitas)
Jadi, saya menyimpulkan bahwa ketika kita memanggil metode flush () pada objek Sesi, maka itu tidak mendapatkan komit tetapi mengenai database dan mengeksekusi kueri dan mendapatkan rollback juga.
Untuk melakukan kita menggunakan commit () pada objek Transaction.
Pembilasan Sesi membuat data yang saat ini ada dalam sesi disinkronkan dengan apa yang ada di database.
Lebih lanjut di situs web Hibernate:
flush()
berguna, karena sama sekali tidak ada jaminan tentang kapan Sesi mengeksekusi panggilan JDBC, hanya urutan eksekusi panggilan tersebut - kecuali yang Anda gunakan flush()
.
Anda mungkin menggunakan flush
untuk memaksa batasan validasi direalisasikan dan dideteksi di tempat yang diketahui daripada saat transaksi dilakukan. Mungkin yang commit
dipanggil secara implisit oleh beberapa logika kerangka kerja, melalui logika deklaratif, wadah, atau oleh template. Dalam kasus ini, pengecualian apa pun yang dilemparkan mungkin sulit ditangkap dan ditangani (bisa jadi terlalu tinggi dalam kode).
Misalnya, jika Anda save()
memiliki objek EmailAddress baru, yang memiliki batasan unik pada alamat, Anda tidak akan mendapatkan kesalahan hingga Anda melakukannya.
Memanggil flush()
memaksa baris untuk disisipkan, mengeluarkan Exception jika ada duplikat.
Namun, Anda harus memutar kembali sesi setelah pengecualian.
Saya hanya ingin menggabungkan semua jawaban yang diberikan di atas dan juga menghubungkan metode Flush () dengan Session.save () untuk memberikan lebih banyak perhatian
Hibernate save () dapat digunakan untuk menyimpan entitas ke database. Kita dapat memanggil metode ini di luar transaksi, itulah mengapa saya tidak suka metode ini untuk menyimpan data. Jika kita menggunakan ini tanpa transaksi dan kita memiliki cascading antar entitas, maka hanya entitas utama yang disimpan kecuali kita membilas sesi.
flush (): Memaksa sesi untuk dibilas. Ini digunakan untuk menyinkronkan data sesi dengan database.
Saat Anda memanggil session.flush (), pernyataan dijalankan dalam database tetapi tidak akan dikomit. Jika Anda tidak memanggil session.flush () dan jika Anda memanggil session.commit (), metode commit () secara internal akan mengeksekusi pernyataan dan melakukan.
Jadi komit () = flush + komit. Jadi session.flush () hanya mengeksekusi pernyataan dalam database (tapi tidak melakukan) dan pernyataan TIDAK DI DALAM MEMORI lagi. Itu hanya memaksa sesi untuk memudar.
Beberapa poin penting:
Kita harus menghindari penyimpanan di luar batas transaksi, jika tidak entitas yang dipetakan tidak akan disimpan menyebabkan ketidakkonsistenan data. Sangat normal untuk melupakan sesi flushing karena tidak ada pengecualian atau peringatan apa pun. Secara default, Hibernate akan menghapus perubahan secara otomatis untuk Anda: sebelum beberapa eksekusi kueri saat transaksi dilakukan Mengizinkan untuk secara eksplisit menghapus Sesi memberikan kontrol yang lebih baik yang mungkin diperlukan dalam beberapa keadaan (untuk mendapatkan ID yang ditetapkan, untuk mengontrol ukuran Sesi )
The flush()
Metode menyebabkan Hibernate untuk flush sesi. Anda dapat mengkonfigurasi Hibernate untuk menggunakan mode pembilasan untuk sesi dengan menggunakan setFlushMode()
metode. Untuk mendapatkan mode flush untuk sesi saat ini, Anda dapat menggunakan getFlushMode()
metode. Untuk mengecek, apakah session itu kotor, Anda bisa menggunakan isDirty()
metode. Secara default, Hibernate mengelola pembilasan sesi.
Seperti yang tertera dalam dokumentasi:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
Pembilasan
Pembilasan adalah proses sinkronisasi keadaan konteks persistensi dengan database yang mendasarinya. The
EntityManager
dan HibernateSession
mengekspos serangkaian metode, di mana pengembang aplikasi dapat mengubah status persisten dari suatu entitas.Konteks persistensi bertindak sebagai cache tulis di belakang transaksional, mengantri setiap perubahan status entitas. Seperti cache di belakang penulisan, perubahan pertama kali diterapkan dalam memori dan disinkronkan dengan database selama waktu flush. Operasi flush mengambil setiap perubahan status entitas dan menerjemahkannya menjadi pernyataan
INSERT
,UPDATE
atauDELETE
.Strategi pembilasan diberikan oleh flushMode dari Sesi Hibernasi yang sedang berjalan. Meskipun JPA hanya mendefinisikan dua strategi pembilasan (
AUTO
danCOMMIT
), Hibernate memiliki spektrum jenis pembilasan yang jauh lebih luas:
ALWAYS
: Mengosongkan Sesi sebelum setiap kueri;AUTO
: Ini adalah mode default dan menghapus Sesi hanya jika perlu;COMMIT
: Sesi mencoba untuk menunda flush hingga Transaksi saat ini dilakukan, meskipun mungkin juga flush sebelum waktunya;MANUAL
: Sesi pembilasan didelegasikan ke aplikasi, yang harus memanggilSession.flush()
secara eksplisit untuk menerapkan perubahan konteks persistensi.Secara default, Hibernate menggunakan
AUTO
mode flush yang memicu flush dalam keadaan berikut:
- sebelum melakukan Transaksi;
- sebelum mengeksekusi query JPQL / HQL yang tumpang tindih dengan antrian tindakan entitas;
- sebelum menjalankan kueri SQL asli apa pun yang tidak memiliki sinkronisasi terdaftar.
Menelepon EntityManager#flush
memang memiliki efek samping . Ini mudah digunakan untuk tipe entitas dengan nilai ID yang dihasilkan (nilai urutan): ID semacam itu hanya tersedia setelah sinkronisasi dengan lapisan persistensi yang mendasarinya. Jika ID ini diperlukan sebelum transaksi saat ini berakhir (untuk tujuan logging misalnya), diperlukan pembersihan sesi.