Domanda

Dall'API, ho visto 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 !!

È stato utile?

Soluzione

Dal Forum di ibernazione :

  

Questo dal libro Hibernate in Action. Bene, leggi questo ..


Recupero oggetti per identificatore Il frammento di codice Hibernate seguente recupera un oggetto User dal database:

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

Il metodo get () è speciale perché l'identificatore identifica in modo univoco un singolo istanza di una classe. Quindi è comune che le applicazioni utilizzino l'identificatore come a comoda gestione di un oggetto persistente. Il recupero per identificatore può utilizzare la cache quando si recupera un oggetto, evitando un hit del database se l'oggetto è 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 dell'utente richiesta. La differenza è banale:

Se load () non riesce a trovare l'oggetto nella cache o nel database, esiste un'eccezione gettato. Il metodo load () non restituisce mai null. Il metodo get () ritorna null se l'oggetto non è stato trovato.

Il metodo load () può restituire un proxy anziché un'istanza permanente reale. Un proxy è un segnaposto che attiva il caricamento dell'oggetto reale quando lo è accessibile per la prima volta; Sul d'altra parte, get () non restituisce mai un proxy. Scegliere tra get () e load () è facile: se sei sicuro del persistente esiste un oggetto e l'inesistenza sarebbe considerata eccezionale, load () è a buona opzione. Se non sei sicuro che ci sia un'istanza persistente con il dato identificatore, usa get () e verifica il valore restituito per vedere se è nullo. Utilizzando load () ha un'ulteriore implicazione: l'applicazione può recuperare un riferimento valido (un proxy) a a istanza persistente senza colpire il database per recuperarne lo stato persistente. Così load () potrebbe non generare un'eccezione quando non trova l'oggetto persistente nella cache o nel database; l'eccezione verrebbe lanciata più tardi, quando il proxy si accede. Naturalmente, il recupero di un oggetto tramite identificatore non è flessibile come l'utilizzo di un arbitrario interrogazioni.

Altri suggerimenti

Bene, almeno in nhibernate, session.Get (id) caricherà l'oggetto dal database, mentre session.Load (id) crea solo un oggetto proxy senza uscire dal server. Funziona proprio come qualsiasi altra proprietà caricata in modo pigro nei tuoi POCO (o POJO :). È quindi possibile utilizzare questo proxy come riferimento all'oggetto stesso per creare relazioni, ecc.

Pensalo come avere un oggetto che mantiene solo l'ID e che caricherà il resto se mai ne avrai bisogno. Se lo stai solo passando per creare relazioni (come gli FK), l'id è tutto ciò di cui hai bisogno.

session.load () restituirà sempre un "proxy" (termine di ibernazione) senza colpire il database. In Hibernate, il proxy è un oggetto con il valore identificativo specificato, le sue proprietà non sono ancora inizializzate, sembra solo un oggetto falso temporaneo.     Se non viene trovata alcuna riga, verrà generata una ObjectNotFoundException.

session.get () ha sempre colpito il database e restituito l'oggetto reale, un oggetto che rappresenta la riga del database, non un proxy.     Se non viene trovata alcuna riga, restituisce null.

Anche le prestazioni con questi metodi rendono diff. tra due ...

Un altro punto extra ::

Il metodo get della classe Hibernate Session restituisce null se l'oggetto non viene trovato nella cache e nel database. mentre il metodo load () genera ObjectNotFoundException se l'oggetto non viene trovato nella cache e nel database ma non restituisce mai null.

Una conseguenza indiretta dell'uso di "caricamento" invece di " ottieni " è che il blocco ottimistico che utilizza un attributo versione potrebbe non funzionare come previsto. Se un carico crea semplicemente un proxy e non legge dal database, la proprietà della versione non viene caricata. La versione verrà caricata solo quando / se in seguito fai riferimento a una proprietà sull'oggetto, attivando una selezione. Nel frattempo, un'altra sessione può aggiornare l'oggetto e la tua sessione non avrà la versione originale di cui ha bisogno per eseguire il controllo del blocco ottimistico, quindi l'aggiornamento della sessione sovrascriverà l'aggiornamento dell'altra sessione senza preavviso.

Ecco un tentativo di delineare questo scenario con due sessioni che lavorano con un oggetto con lo stesso identificatore. La versione iniziale per l'oggetto 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 ottimista, ma qui avrà successo.

Utilizzando " get " invece di "caricamento" aggira il problema, perché get emetterà immediatamente una selezione e i numeri di versione verranno caricati nei momenti corretti per il controllo del blocco ottimistico.

Inoltre dobbiamo stare attenti durante l'utilizzo di load in quanto genererà un'eccezione se l'oggetto non è presente. Dobbiamo usarlo solo quando siamo sicuri che l'oggetto esiste.

Un'ottima spiegazione è disponibile all'indirizzo http: // www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load ():
Restituirà sempre un proxy & # 8220; & & 8221; (Termine di ibernazione) senza colpire il database.
In Hibernate, il proxy è un oggetto con il valore di identificatore specificato, le sue proprietà non sono ancora inizializzate, sembra solo un oggetto falso temporaneo.
Restituirà sempre un oggetto proxy con il valore di identità specificato, anche se il valore di identità non esiste nel database. Tuttavia, quando provi a inizializzare un proxy recuperandone le proprietà dal database, colpirà il database con l'istruzione select. Se non viene trovata alcuna riga, verrà generata una ObjectNotFoundException.
session.get ():
Colpisce sempre il database (se non si trova nella cache) e restituisce l'oggetto reale, un oggetto che rappresenta la riga del database, non un proxy.
Se non viene trovata alcuna riga, restituisce null.

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

Il metodo

get () restituisce null se non è possibile trovare l'oggetto. Il metodo load () può restituire un proxy anziché un'istanza reale persistente get () non restituisce mai un proxy.

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