Hibernate svuota il mio object persistente aggiornato quando si chiama session.close () con FlushMode.AUTO?

Se FlushMode.AUTO è impostato, Hibernate svuota il mio object persistente aggiornato quando chiamo session.close ()?

So che session.close () normalmente non scarica la sessione, ma non sono sicuro di come FlushMode.AUTO abbia effetto su questo.

Dai documenti:

FlushMode.AUTO
A volte la sessione viene svuotata prima dell’esecuzione della query per garantire che le query non restituiscano mai lo stato non aggiornato. Questa è la modalità flush predefinita.

Questo significa che posso fare affidamento su Hibernate per verificare che le mie modifiche vengano cancellate qualche volta prima che la mia sessione venga chiusa?

Esempio di codice ridotto:

Session session = HibernateSessionFactory.getSession(); PersistedObject p = session.get(PersistedObject.class,id); p.setSomeProperty(newValue); session.close(); 

AGGIORNARE
Secondo i documenti, questi sono i luoghi in cui la sessione verrà chiusa (quando viene utilizzato AUTO)

  • prima di alcune esecuzioni di query
  • da org.hibernate.Transaction.commit ()
  • da Session.flush ()

Questo non dice nulla su Session.close ()

Hibernate svuota il mio object persistente aggiornato quando si chiama session.close () (usando FlushMode.AUTO)?

No, non lo sarà, e dovresti usare una transazione con confini ben definiti . Citando l’accesso ai dati non transazionale e la modalità di auto-commit :

Lavoro non transazionale con Hibernate

Guarda il seguente codice, che accede al database senza limiti di transazione:

 Session session = sessionFactory.openSession(); session.get(Item.class, 123l); session.close(); 

Per impostazione predefinita, in un ambiente Java SE con una configurazione JDBC, questo è ciò che accade se si esegue questo snippet:

  1. Viene aperta una nuova sessione. Non ottiene una connessione al database a questo punto.
  2. La chiamata a get () triggers un SELECT SQL. La sessione ora ottiene una connessione JDBC dal pool di connessioni. Hibernate, per impostazione predefinita, distriggers immediatamente la modalità autocommit su questa connessione con setAutoCommit (false). Ciò avvia in modo efficace una transazione JDBC!
  3. SELECT viene eseguito all’interno di questa transazione JDBC. La sessione viene chiusa e la connessione viene restituita al pool e rilasciata da Hibernate. Le chiamate di ibernazione si chiudono () sulla connessione JDBC. Cosa succede alla transazione non impegnata?

La risposta a questa domanda è “Dipende!” Le specifiche JDBC non dicono nulla sulle transazioni in sospeso quando close () viene chiamato su una connessione. Quello che succede dipende da come i produttori implementano le specifiche. Ad esempio, con i driver JDBC Oracle, la chiamata a close () esegue il commit della transazione! La maggior parte dei fornitori JDBC prende la rotta corretta e ripristina qualsiasi transazione in sospeso quando l’object Connessione JDBC viene chiuso e la risorsa viene restituita al pool.

Ovviamente, questo non sarà un problema per il SELECT che hai eseguito, ma guarda questa variazione:

 Session session = getSessionFactory().openSession(); Long generatedId = session.save(item); session.close(); 

Questo codice genera un’istruzione INSERT, eseguita all’interno di una transazione che non viene mai eseguita o ripristinata. Su Oracle, questo pezzo di codice inserisce i dati in modo permanente; in altri database, potrebbe non farlo. (Questa situazione è leggermente più complicata: l’INSERT viene eseguito solo se il generatore di identificatori lo richiede.Ad esempio, un valore identificativo può essere ottenuto da una sequenza senza INSERT. L’ quadro persistente viene quindi accodata fino all’inserimento a tempo zero – che mai avviene in questo codice . Una strategia di identity framework richiede un INSERT immediato per il valore da generare.)

Bottom line: usa la demarcazione della transazione esplicita.

chiudere una sessione arriverà sempre al lavoro sul database. Flushmode.AUTO svuota il lavoro nel database quando sono presenti modifiche e stai interrompendo la tabella con i record modificati.