Kiedy aktualizujemy rekord, możemy użyć session.flush()
z Hibernate. Jaka jest potrzeba flush()
?
110
Opróżnianie sesji wymusza na Hibernate synchronizację stanu pamięci Session
z bazą danych (tj. Zapis zmian w bazie danych). Domyślnie Hibernacja automatycznie opróżni zmiany:
Zezwolenie na jawne opróżnienie Session
daje dokładniejszą kontrolę, która może być wymagana w niektórych okolicznościach (aby uzyskać przypisany identyfikator, kontrolować rozmiar sesji, ...).
id = session.save(obj);
i transakcja jest zatwierdzana w następnej linii, ale obj nie jest zapisywana do DB, dlaczego? 2) Zapisałem obj używającsession.save(obj);
z zatwierdzeniem i podczas powrotu użyłemreturn obj.getprimaryID();
W tym przypadku obj jest zapisywany w DB. Dlaczego więc tak się dzieje?Jak słusznie powiedzieliśmy w powyższych odpowiedziach, dzwoniąc
flush()
wymusza hibernację w celu wykonania poleceń SQL w bazie danych. Ale zrozum, że zmiany nie są jeszcze „zatwierdzone”. Więc po wykonaniu flush i przed zatwierdzeniem, jeśli uzyskasz bezpośredni dostęp do DB (powiedzmy z zachęty SQL) i sprawdzisz zmodyfikowane wiersze, NIE zobaczysz zmian.To samo, co otwarcie 2 sesji poleceń SQL. A zmiany dokonane w jednej sesji nie są widoczne dla innych, dopóki nie zostaną zatwierdzone.
źródło
Wiem tylko, że kiedy wywołujemy,
session.flush()
nasze instrukcje są wykonywane w bazie danych, ale nie są zatwierdzane.Załóżmy, że nie wywołujemy
flush()
metody na obiekcie sesji i jeśli wywołamy metodę commit, to wewnętrznie wykona ona pracę polegającą na wykonaniu instrukcji w bazie danych, a następnie zatwierdzeniu.commit=flush+commit
(w przypadku funkcjonalności)Dlatego dochodzę do wniosku, że kiedy wywołujemy metodę flush () na obiekcie Session, to nie otrzymuje ona zatwierdzenia, ale trafia do bazy danych i wykonuje zapytanie, a także otrzymuje wycofanie.
W celu zatwierdzenia używamy funkcji commit () na obiekcie Transaction.
źródło
Opróżnianie sesji powoduje, że dane, które są aktualnie w sesji, są zsynchronizowane z tym, co znajduje się w bazie danych.
Więcej na stronie Hibernate:
flush()
jest przydatne, ponieważ nie ma absolutnie żadnej gwarancji, kiedy sesja wykona wywołania JDBC, tylko kolejność, w jakiej są wykonywane - z wyjątkiem tego, którego używaszflush()
.źródło
Możesz użyć
flush
do wymuszenia realizacji i wykrycia ograniczeń walidacji w znanym miejscu, a nie wtedy, gdy transakcja zostanie zatwierdzona. Może się zdarzyć, żecommit
zostanie wywołany niejawnie przez jakąś logikę struktury, logikę deklaratywną, kontener lub szablon. W takim przypadku każdy zgłoszony wyjątek może być trudny do przechwycenia i obsługi (może być zbyt wysoki w kodzie).Na przykład, jeśli masz
save()
nowy obiekt EmailAddress, który ma unikalne ograniczenie adresu, nie otrzymasz błędu, dopóki nie zatwierdzisz.Wywołanie
flush()
wymusza wstawienie wiersza, zgłaszając wyjątek, jeśli istnieje duplikat.Jednak po wystąpieniu wyjątku konieczne będzie wycofanie sesji.
źródło
Chciałbym tylko zebrać wszystkie odpowiedzi podane powyżej, a także powiązać metodę Flush () z Session.save (), aby nadać większe znaczenie
Hibernate save () można użyć do zapisania jednostki do bazy danych. Możemy wywołać tę metodę poza transakcją, dlatego nie podoba mi się ta metoda zapisywania danych. Jeśli używamy tego bez transakcji i mamy kaskadowanie między jednostkami, to tylko jednostka podstawowa zostanie zapisana, chyba że opróżnimy sesję.
flush (): wymusza flush sesji. Służy do synchronizacji danych sesji z bazą danych.
Kiedy wywołujesz session.flush (), instrukcje są wykonywane w bazie danych, ale nie zostaną zatwierdzone. Jeśli nie wywołasz session.flush () i jeśli wywołasz session.commit (), to wewnętrznie metoda commit () wykonuje instrukcję i zatwierdza.
Więc commit () = flush + commit. Tak więc session.flush () po prostu wykonuje instrukcje w bazie danych (ale nie zatwierdza), a instrukcje NIE SĄ już W PAMIĘCI. Po prostu zmusza sesję do spłukiwania.
Kilka ważnych punktów:
Powinniśmy unikać zapisywania poza granicami transakcji, w przeciwnym razie zmapowane jednostki nie zostaną zapisane, powodując niespójność danych. Zapominanie o opróżnianiu sesji jest bardzo normalne, ponieważ nie powoduje to żadnych wyjątków ani ostrzeżeń. Domyślnie Hibernate automatycznie opróżni zmiany: przed wykonaniem niektórych zapytań po zatwierdzeniu transakcji Zezwolenie na jawne opróżnienie Sesji daje dokładniejszą kontrolę, która może być wymagana w pewnych okolicznościach (aby uzyskać przypisany identyfikator, aby kontrolować rozmiar sesji )
źródło
flush()
Metoda powoduje Hibernate do spłukiwania sesję. Możesz skonfigurować hibernację, aby używała trybu opróżniania sesji przy użyciusetFlushMode()
metody. Aby uzyskać tryb flush dla bieżącej sesji, możesz użyćgetFlushMode()
metody. Aby sprawdzić, czy sesja jest brudna, możesz użyćisDirty()
metody. Domyślnie Hibernate zarządza opróżnianiem sesji.Jak podano w dokumentacji:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
źródło
Dzwonienie
EntityManager#flush
ma skutki uboczne . Jest wygodnie używany w przypadku typów jednostek z wygenerowanymi wartościami identyfikatora (wartości sekwencji): taki identyfikator jest dostępny tylko po synchronizacji z podstawową warstwą trwałości. Jeśli ten identyfikator jest wymagany przed zakończeniem bieżącej transakcji (na przykład do celów logowania), wymagane jest opróżnienie sesji.źródło
Dzięki tej metodzie wywołujesz proces spłukiwania. Ten proces synchronizuje stan bazy danych ze stanem sesji, wykrywając zmiany stanu i wykonując odpowiednie instrukcje SQL.
źródło