Ibernazione: differenza tra session.get e session.load

Dall’API, ho potuto vedere che ha qualcosa a che fare con il proxy. Ma non sono riuscito a trovare molte informazioni sul proxy e non capisco la differenza tra chiamare session.get e session.load . Qualcuno potrebbe spiegarmi o indirizzarmi a una pagina di riferimento?

Grazie!!

Dal forum di Hibernate :

Questo dal libro Hibernate in Action. Bravo a leggere questo ..


Recupero di oggetti per identificativo Il seguente snippet di codice di Hibernate recupera un object User dal database:

 User user = (User) session.get(User.class, userID); 

Il metodo get () è speciale perché l’identificatore identifica in modo univoco una singola istanza di una class. Quindi è normale che le applicazioni utilizzino l’identificatore come comoda maniglia per un object persistente. Recupero per identificatore può utilizzare la cache quando si recupera un object, evitando un hit del database se l’object è già memorizzato nella cache. Hibernate fornisce anche un metodo load ():

 User user = (User) session.load(User.class, userID); 

Il metodo load () è più vecchio; get () è stato aggiunto all’API di Hibernate a causa della richiesta dell’utente. La differenza è banale:

Se load () non riesce a trovare l’object nella cache o nel database, viene generata un’eccezione. Il metodo load () non restituisce mai null. Il metodo get () restituisce null se l’object non può essere trovato.

Il metodo load () può restituire un proxy invece di un’istanza reale persistente. Un proxy è un segnaposto che triggers il caricamento dell’object reale al momento dell’accesso per la prima volta; D’altra parte, get () non restituisce mai un proxy. Scegliere tra get () e load () è semplice: se si è certi che l’object persistente esista e la non esistenza sia considerata eccezionale, load () è una buona opzione. Se non sei sicuro che ci sia un’istanza persistente con l’identificatore fornito, usa get () e verifica il valore restituito per vedere se è nullo. L’utilizzo di load () ha un’ulteriore implicazione: l’applicazione può recuperare un riferimento valido (un proxy) a un’istanza persistente senza colpire il database per recuperarne lo stato permanente. Quindi load () potrebbe non generare un’eccezione quando non trova l’object persistente nella cache o nel database; l’eccezione verrebbe generata più tardi, quando si accede al proxy. Naturalmente, il recupero di un object per identificatore non è così flessibile come l’utilizzo di query arbitrarie.

Bene, almeno in nhibder, session.Get (id) caricherà l’object dal database, mentre session.Load (id) solo creerà un object proxy senza uscire dal server. Funziona esattamente come ogni altra proprietà lazy-loaded nei tuoi POCO (o POJOs :). È quindi ansible utilizzare questo proxy come riferimento all’object stesso per creare relazioni, ecc.

Pensa ad avere un object che mantiene solo l’ID e che caricherà il resto se ne avrai mai bisogno. Se lo fai passare per creare relazioni (come gli FK), l’id è tutto ciò di cui avrai bisogno.

session.load () restituirà sempre un “proxy” (termine Hibernate) senza colpire il database. In Hibernate, il proxy è un object con il valore di identificatore specificato, le sue proprietà non sono ancora inizializzate, assomigliano a un object finto temporaneo. Se nessuna riga trovata, genera una ObjectNotFoundException.

session.get () colpisce sempre il database e restituisce l’object reale, un object che rappresenta la riga del database, non il proxy. Se non viene trovata alcuna riga, restituisce null.

Le prestazioni con questi metodi rendono anche diff. tra due…

Un altro punto extra ::

ottiene il metodo della class Hibernate restituisce null se l’object non viene trovato nella cache e sul database. mentre il metodo load () lancia ObjectNotFoundException se l’object non viene trovato sulla cache e sul database, ma non restituisce mai null.

Una conseguenza indiretta dell’utilizzo di “load” invece di “get” è che il blocco ottimistico utilizzando un attributo di versione potrebbe non funzionare come ci si aspetterebbe. Se un carico crea semplicemente un proxy e non viene letto dal database, la proprietà della versione non viene caricata. La versione verrà caricata solo quando / se in seguito si farà riferimento a una proprietà sull’object, triggersndo una selezione. Nel frattempo, un’altra sessione può aggiornare l’object e la tua sessione non avrà la versione originale di cui ha bisogno per eseguire il controllo di blocco ottimistico – così l’aggiornamento della sessione sovrascriverà l’aggiornamento dell’altra sessione senza preavviso.

Ecco un tentativo di delineare questo scenario con due sessioni di lavoro con un object con lo stesso identificatore. La versione iniziale per l’object nel DB è 10.

 Session 1 Session 2 --------- --------- Load object Wait a while.. Load object Modify object property [triggers db 'select' - version read as 10] Commit [triggers db update, version modified to 11] Modify object property [triggers db 'select' - version read as 11] Commit [triggers db update, version modified to 12] 

In realtà vogliamo che il commit della sessione 1 fallisca con un’eccezione di blocco ottimistico, ma ci riuscirà.

L’uso di “get” invece di “load” risolve il problema, perché get emetterà immediatamente una selezione e i numeri di versione verranno caricati ai tempi corretti per il controllo ottimistico del blocco.

Inoltre dobbiamo stare attenti durante l’utilizzo del carico in quanto genererà un’eccezione se l’object non è presente. Dobbiamo usarlo solo quando siamo sicuri che l’object esiste.

Una spiegazione eccellente si trova su http://www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load ():
Restituirà sempre un “proxy” (termine Hibernate) senza colpire il database.
In Hibernate, il proxy è un object con il valore di identificatore specificato, le sue proprietà non sono ancora inizializzate, assomigliano a un object finto temporaneo.
Restituirà sempre un object proxy con il valore di id quadro specificato, anche il valore di identity framework non è presente nel database. Tuttavia, quando si tenta di inizializzare un proxy recuperando le sue proprietà dal database, questo colpirà il database con l’istruzione select. Se non viene trovata alcuna riga, verrà lanciata una ObjectNotFoundException.
session.get ():
Colpisce sempre il database (se non viene trovato nella cache) e restituisce l’object reale, un object che rappresenta la riga del database, non il proxy.
Se non viene trovata alcuna riga, restituisce null.

load () non riesce a trovare l’object dalla cache o dal database, viene generata un’eccezione e il metodo load () non restituisce mai null.

Il metodo get () restituisce null se l’object non può essere trovato. Il metodo load () può restituire un proxy anziché un’istanza persistente reale get () non restituisce mai un proxy.