Risposte:
Lo svuotamento della sessione forza Hibernate a sincronizzare lo stato in memoria di Session
con il database (cioè a scrivere le modifiche nel database). Per impostazione predefinita, Hibernate scaricherà automaticamente le modifiche:
Consentire di svuotare esplicitamente il Session
dà un controllo più preciso che può essere richiesto in alcune circostanze (per ottenere un ID assegnato, per controllare la dimensione della Sessione, ...).
id = session.save(obj);
e la transazione viene eseguita nella riga successiva ma obj non viene salvato a DB, perché? 2) Ho salvato obj usando session.save(obj);
con commit e durante il ritorno ho usato return obj.getprimaryID();
In questo caso obj viene salvato su DB. Allora perché questo comportamento sta accadendo?
Come giustamente detto nelle risposte precedenti, chiamando flush()
forziamo l'ibernazione per eseguire i comandi SQL su Database. Ma comprendi che i cambiamenti non sono ancora "impegnati". Quindi, dopo aver eseguito il flush e prima di eseguire il commit, se accedi direttamente al DB (diciamo dal prompt SQL) e controlli le righe modificate, NON vedrai le modifiche.
Equivale all'apertura di 2 sessioni di comandi SQL. E le modifiche apportate in 1 sessione non sono visibili agli altri finché non vengono eseguite.
So solo che quando chiamiamo le session.flush()
nostre istruzioni vengono eseguite nel database ma non impegnate.
Supponiamo di non chiamare il flush()
metodo sull'oggetto sessione e se chiamiamo il metodo commit, internamente eseguirà le istruzioni sul database e quindi eseguirà il commit.
commit=flush+commit
(in caso di funzionalità)
Quindi, concludo che quando chiamiamo il metodo flush () sull'oggetto Session, allora non ottiene il commit ma colpisce il database ed esegue la query e ottiene anche il rollback.
Per eseguire il commit usiamo commit () sull'oggetto Transaction.
Lo svuotamento della sessione ottiene i dati attualmente nella sessione sincronizzati con ciò che è nel database.
Maggiori informazioni sul sito Web di Hibernate:
flush()
è utile, perché non ci sono assolutamente garanzie su quando la sessione esegue le chiamate JDBC, solo l'ordine in cui vengono eseguite, tranne che si usa flush()
.
È possibile utilizzare flush
per forzare la realizzazione e il rilevamento dei vincoli di convalida in un luogo noto anziché quando viene eseguito il commit della transazione. Può essere che commit
venga chiamato implicitamente da una logica del framework, tramite la logica dichiarativa, il contenitore o un modello. In questo caso, qualsiasi eccezione generata potrebbe essere difficile da intercettare e gestire (potrebbe essere troppo alta nel codice).
Ad esempio, se save()
utilizzi un nuovo oggetto EmailAddress, che ha un vincolo univoco sull'indirizzo, non riceverai un errore finché non effettui il commit.
La chiamata flush()
forza l'inserimento della riga, generando un'eccezione se è presente un duplicato.
Tuttavia, sarà necessario ripristinare la sessione dopo l'eccezione.
Vorrei solo associare tutte le risposte fornite sopra e correlare anche il metodo Flush () con Session.save () in modo da dare più importanza
Hibernate save () può essere utilizzato per salvare l'entità nel database. Possiamo invocare questo metodo al di fuori di una transazione, ecco perché non mi piace questo metodo per salvare i dati. Se lo usiamo senza transazione e abbiamo una cascata tra le entità, viene salvata solo l'entità primaria a meno che non svuotiamo la sessione.
flush (): forza lo scaricamento della sessione. Viene utilizzato per sincronizzare i dati della sessione con il database.
Quando chiamate session.flush (), le istruzioni vengono eseguite nel database ma non verrà eseguito il commit. Se non chiami session.flush () e se chiami session.commit (), il metodo commit () internamente esegue l'istruzione e si impegna.
Quindi commit () = flush + commit. Quindi session.flush () esegue solo le istruzioni nel database (ma non esegue il commit) e le istruzioni NON sono più IN MEMORIA. Forza solo lo scarico della sessione.
Pochi punti importanti:
Dobbiamo evitare di salvare al di fuori del confine della transazione, altrimenti le entità mappate non verranno salvate causando incoerenze nei dati. È molto normale dimenticare di svuotare la sessione perché non genera eccezioni o avvisi. Per impostazione predefinita, Hibernate scaricherà automaticamente le modifiche per te: prima che alcune esecuzioni di query quando una transazione venga salvata Consentire di svuotare esplicitamente la Sessione fornisce un controllo più preciso che potrebbe essere richiesto in alcune circostanze (per ottenere un ID assegnato, per controllare la dimensione della Sessione )
Il flush()
metodo fa in modo che Hibernate scarichi la sessione. È possibile configurare Hibernate per utilizzare la modalità di svuotamento per la sessione utilizzando il setFlushMode()
metodo. Per ottenere la modalità flush per la sessione corrente, puoi usare getFlushMode()
method. Per verificare se la sessione è sporca, puoi usare il isDirty()
metodo. Per impostazione predefinita, Hibernate gestisce lo svuotamento delle sessioni.
Come indicato nella documentazione:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
risciacquo
Lo svuotamento è il processo di sincronizzazione dello stato del contesto di persistenza con il database sottostante. E
EntityManager
HibernateSession
espongono una serie di metodi, attraverso i quali lo sviluppatore dell'applicazione può modificare lo stato persistente di un'entità.Il contesto di persistenza funge da cache write-behind transazionale, accodando qualsiasi modifica dello stato dell'entità. Come qualsiasi cache write-behind, le modifiche vengono prima applicate in memoria e sincronizzate con il database durante il tempo di scaricamento. L'operazione di incasso prende ogni entità cambiamento di stato e lo traduce in un
INSERT
,UPDATE
o diDELETE
dichiarazione.La strategia di svuotamento è data dal flushMode della sessione Hibernate attualmente in esecuzione. Sebbene JPA definisca solo due strategie di lavaggio (
AUTO
eCOMMIT
), Hibernate ha uno spettro molto più ampio di tipi di lavaggio:
ALWAYS
: Svuota la sessione prima di ogni query;AUTO
: Questa è la modalità predefinita e scarica la sessione solo se necessario;COMMIT
: La Sessione cerca di ritardare lo scaricamento fino a quando non viene confermata la Transazione corrente, sebbene potrebbe anche scaricarsi prematuramente;MANUAL
: Lo svuotamento della sessione è delegato all'applicazione, che deve chiamareSession.flush()
esplicitamente per applicare le modifiche al contesto di persistenza.Per impostazione predefinita, Hibernate utilizza la
AUTO
modalità flush che attiva un flush nelle seguenti circostanze:
- prima di effettuare una transazione;
- prima di eseguire una query JPQL / HQL che si sovrappone alle azioni dell'entità in coda;
- prima di eseguire qualsiasi query SQL nativa senza sincronizzazione registrata.
La chiamata EntityManager#flush
ha effetti collaterali . È convenientemente utilizzato per i tipi di entità con valori ID generati (valori di sequenza): tale ID è disponibile solo al momento della sincronizzazione con il livello di persistenza sottostante. Se questo ID è richiesto prima del termine della transazione corrente (ad esempio per scopi di registrazione), è necessario svuotare la sessione.