Yanıtlar:
Oturumu temizlemek, Hazırda Bekletme'yi Session, veritabanının bellek içi durumunu veritabanıyla senkronize etmeye zorlar (yani değişiklikleri veritabanına yazmaya). Varsayılan olarak, Hazırda Bekletme değişiklikleri sizin için otomatik olarak temizleyecektir:
Açıkça yıkamaya izin vermek Session, bazı durumlarda gerekli olabilecek daha ince kontrol sağlar (atanan bir kimlik almak, Oturumun boyutunu kontrol etmek için, ...).
id = session.save(obj);ve işlem hemen sonraki satırda gerçekleştiriliyor ancak obj kaydedilmiyor DB'ye, Neden? 2) session.save(obj);commit ile objeyi kaydettim ve geri dönerken kullandım return obj.getprimaryID();Bu durumda obj DB'ye kaydedildi. Öyleyse neden bu davranış oluyor?
Yukarıdaki cevaplarda doğru bir şekilde belirtildiği gibi, çağırarak flush(), Veri Tabanında SQL komutlarını yürütmek için hazırda bekletmeye zorlarız. Ancak değişikliklerin henüz "taahhüt edilmediğini" anlayın. Bu nedenle, flush yaptıktan sonra ve commit yapmadan önce, DB'ye doğrudan erişirseniz (örneğin SQL komut isteminden) ve değiştirilen satırları kontrol ederseniz, değişiklikleri GÖRMEZSİNİZ.
Bu, 2 SQL komut oturumu açmakla aynıdır. Ve 1 seansta yapılan değişiklikler, taahhüt edilene kadar başkaları tarafından görülmez.
Yalnızca session.flush()ifadelerimizin veritabanında yürütüldüğünü ancak taahhüt edilmediğini biliyorum .
Diyelim ki flush(), oturum nesnesinde yöntemi çağırmıyoruz ve eğer commit yöntemini çağırırsak, veritabanında ifadeleri yürütme ve sonra taahhüt etme işini dahili olarak yapacaktır.
commit=flush+commit (işlevsellik durumunda)
Böylece, Session nesnesinde flush () metodunu çağırdığımızda, commit almadığı, veritabanına isabet ettiği ve sorguyu çalıştırdığı ve geri dönüşü de aldığı sonucuna vardım.
Taahhüt etmek için İşlem nesnesinde commit () kullanıyoruz.
Oturumu temizlemek, o anda oturumda bulunan verileri veritabanındakilerle eşitlenmiş olarak alır.
Hazırda Beklet web sitesinde daha fazlası:
flush()kullanışlıdır, çünkü Oturum'un JDBC çağrılarını ne zaman yürüteceği konusunda kesinlikle hiçbir garanti yoktur, yalnızca bunların yürütüldüğü sıra - siz kullanmanız dışında flush().
flushDoğrulama kısıtlamalarının işlemin gerçekleştirilmesi yerine bilinen bir yerde gerçekleştirilmesini ve tespit edilmesini zorlamak için kullanabilirsiniz . O olabilircommitBazı çerçeve mantığı, bildirim mantığı, kapsayıcı veya bir şablon aracılığıyla örtük olarak çağrılan . Bu durumda, atılan herhangi bir istisnayı yakalamak ve idare etmek zor olabilir (kodda çok yüksek olabilir).
Örneğin save(), adres üzerinde benzersiz bir kısıtlamaya sahip yeni bir EmailAddress nesnesiyseniz, işleme koyana kadar bir hata almazsınız.
çağrı flush() , satırı eklenmeye zorlar ve bir kopya varsa bir İstisna oluşturur.
Ancak, istisnadan sonra oturumu geri almanız gerekecektir.
Sadece yukarıda verilen tüm cevapları bir araya getirmek ve daha fazla önem vermek için Flush () yöntemini Session.save () ile ilişkilendirmek istiyorum.
Hazırda bekletme kaydetme (), varlığı veritabanına kaydetmek için kullanılabilir. Bu yöntemi bir işlemin dışında çalıştırabiliriz, bu yüzden bu yöntemi veri kaydetmeyi sevmiyorum. Bunu işlem yapmadan kullanırsak ve varlıklar arasında geçiş yaparsak, o zaman oturumu temizlemediğimiz sürece yalnızca birincil varlık kaydedilir.
flush (): Oturumu temizlemeye zorlar. Veri tabanı ile oturum verilerini senkronize etmek için kullanılır.
Session.flush () 'u çağırdığınızda, ifadeler veritabanında yürütülür ancak taahhüt edilmez. Session.flush () 'u çağırmazsanız ve session.commit ()' i çağırırsanız, dahili olarak commit () metodu ifadeyi çalıştırır ve tamamlar.
Yani commit () = flush + commit. Yani session.flush () sadece veri tabanındaki ifadeleri çalıştırır (ancak teslim etmez) ve ifadeler artık BELLEKTE DEĞİLDİR. Sadece oturumu kızarmaya zorlar.
Birkaç önemli nokta:
İşlem sınırlarının dışına çıkmaktan kaçınmalıyız, aksi takdirde eşlenen varlıklar veri tutarsızlığına neden olacak şekilde kaydedilmeyecektir. Herhangi bir istisna veya uyarı atmadığı için oturumu temizlemeyi unutmak çok normaldir. Varsayılan olarak, Hazırda Bekletme, değişiklikleri sizin için otomatik olarak temizleyecektir: bir işlem gerçekleştirildiğinde bazı sorgu yürütmelerinden önce Oturumu açıkça temizlemeye izin vermek, bazı durumlarda gerekli olabilecek daha hassas kontrol sağlar (atanmış bir kimliği almak, Oturumun boyutunu kontrol etmek için) )
flush() Yöntem oturumu temizlemek Hibernate neden olur. setFlushMode()Yöntemi kullanarak Hazırda Bekletme'yi oturum için yıkama modunu kullanacak şekilde yapılandırabilirsiniz . Mevcut oturum için yıkama modunu elde etmek için getFlushMode()yöntemi kullanabilirsiniz . Oturumun kirli olup olmadığını kontrol etmek için kullanabilirsinizisDirty() yöntemi . Varsayılan olarak, Hazırda Bekletme, oturumların yıkanmasını yönetir.
Belgelerde belirtildiği gibi:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
Flushing
Temizleme, kalıcılık bağlamının durumunu temeldeki veritabanıyla senkronize etme işlemidir. Ve
EntityManagerHazırda BekletmeSession, uygulama geliştiricisinin bir varlığın kalıcı durumunu değiştirebileceği bir dizi yöntemi ortaya çıkarır.Kalıcılık bağlamı, herhangi bir varlık durumu değişikliğini sıraya koyan işlemsel bir arkaya yazma önbelleği görevi görür. Herhangi bir arkaya yazma önbelleği gibi, değişiklikler ilk olarak bellekte uygulanır ve temizleme süresi sırasında veritabanıyla senkronize edilir. Temizleme işlemi, her varlık durum değişikliğini alır ve bunu bir
INSERT,UPDATEveyaDELETEifadesine çevirir .Yıkama stratejisi, çalışmakta olan mevcut Hazırda Bekletme Oturumunun flushMode tarafından verilir . JPA yalnızca iki yıkama stratejisi tanımlasa da (
AUTOveCOMMIT), Hibernate çok daha geniş bir yıkama türleri yelpazesine sahiptir:
ALWAYS: Her sorgudan önce Oturumu temizler;AUTO: Bu varsayılan moddur ve Oturumu yalnızca gerekirse temizler;COMMIT: Oturum, mevcut İşlem tamamlanana kadar boşaltmayı ertelemeye çalışır, ancak yine de vaktinden önce boşaltabilir;MANUAL: Oturum temizleme yetkisiSession.flush(), kalıcılık bağlam değişikliklerini uygulamak için açıkça çağırması gereken uygulamaya devredilir .Varsayılan olarak, Hazırda Bekletme
AUTOaşağıdaki durumlarda yıkamayı tetikleyen yıkama modunu kullanır :
- bir İşlem gerçekleştirmeden önce;
- sıraya alınmış varlık eylemleriyle örtüşen bir JPQL / HQL sorgusu yürütmeden önce;
- kayıtlı senkronizasyonu olmayan herhangi bir yerel SQL sorgusunu yürütmeden önce.
Çağrı EntityManager#flushvar yan etkileri . Oluşturulan kimlik değerlerine (sıra değerleri) sahip varlık türleri için uygun şekilde kullanılır: böyle bir kimlik yalnızca temeldeki kalıcılık katmanı ile senkronizasyon üzerine kullanılabilir. Bu kimlik, geçerli işlem sona ermeden önce gerekliyse (örneğin, günlük kaydı amacıyla), oturumun temizlenmesi gerekir.