Quando Hibernate svuota una Sessione, come fa a decidere quali oggetti della sessione sono sporchi?

StackOverflow https://stackoverflow.com/questions/82429

Domanda

La mia conoscenza di Hibernate è che, come gli oggetti vengono caricati dal DB vengono aggiunti alla Sessione.In vari punti, a seconda della configurazione, la sessione viene svuotata.A questo punto, gli oggetti modificati vengono scritti nel database.

Come si fa a Sospensione decidere quali oggetti sono "sporchi" e devono essere scritti?

Fare il proxy generato da Hibernate intercettare le assegnazioni dei campi, e aggiungere l'oggetto sporco di elenco nella Sessione?

O di Sospensione guardare ogni oggetto nella Sessione e confrontarlo con gli oggetti stato originale?

O qualcosa di completamente diverso?

È stato utile?

Soluzione

Sospensione fa/può utilizzare il bytecode generazione (CGLIB) in modo che si sa che un campo è sporco come presto come si chiama il setter (o anche di assegnare al campo afaict).

Questo immediatamente marchi di settore/oggetto sporco, ma non ridurre il numero di oggetti che devono essere sporco-controllato durante filo.Non fa altro che impatto l'attuazione di org.hibernate.engine.EntityEntry.requiresDirtyCheck().Si ancora non un campo di confronto per verificare la sporcizia.

Io dico che il di cui sopra sulla base di un recente strascico attraverso il codice sorgente (3.2.6 GA), con qualsiasi credibilità che aggiunge.I punti di interesse sono:

  • SessionImpl.flush() attiva un onFlush() evento.
  • SessionImpl.list() chiamate autoFlushIfRequired() che innesca un onAutoFlush() evento.(le tabelle di interesse).Che è, le query possono richiamare un colore.È interessante notare che, non a filo che si verifica se non vi è alcuna transazione.
  • Entrambi questi eventi finirà nell' AbstractFlushingEventListener.flushEverythingToExecutions(), che finisce con (tra le altre interessanti località) in flushEntities().
  • Che si ripete dopo ogni entità in sessione (source.getPersistenceContext().getEntityEntries() chiamata DefaultFlushEntityEventListener.onFlushEntity().
  • Alla fine si finisce a dirtyCheck().Che metodo di apportare alcune ottimizzazioni wrt per CGLIB sporco bandiere, ma abbiamo ancora finito per iterare su ogni entità.

Altri suggerimenti

Sospensione scatta un'istantanea dello stato di ogni oggetto che viene caricato in Sessione.Sul filo, ogni oggetto nella Sessione viene confrontato con il corrispondente snapshot per determinare quelli che sono sporchi.Le istruzioni SQL sono emessi come richiesto, e le istantanee vengono aggiornati per riflettere lo stato di pulizia) gli oggetti di Sessione.

Date un'occhiata a org.di sospensione.evento.def.DefaultFlushEntityEventListener.dirtyCheck Ogni elemento della sessione va a questo metodo per determinare se è sporco o non facendo un confronto con un intatto versione (uno dalla cache o uno dal database).

Sospensione di default sporco meccanismo di controllo attraversa corrente collegato entità e corrispondere a tutte le proprietà contro il caricamento iniziale valori in tempo.

È possibile visualizzare meglio questo processo è il seguente schema:

Default automatic dirty checking

Queste risposte sono incomplete (nella migliore delle ipotesi-non sono un esperto qui).Se si dispone di un hib uomo entità nella sessione, si è fatto NULLA, è ancora possibile ottenere un aggiornamento rilasciato quando si chiama save() su di esso.quando?quando un'altra sessione di aggiornamenti che oggetto tra load() e save().qui è il mio esempio di questo: sospensione di imposta sporca bandiera (e problemi di aggiornamento), anche se il client non cambia il valore

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top