java initialize - Qual è il proxy nel contesto del metodo load()di Hibernate?




lazy collection (3)

La documentazione di Hibernate per il metodo load() dice:

Tieni presente che load () genererà un'eccezione irrecuperabile se non ci sono righe corrispondenti del database. Se la classe è mappata con un proxy , load () restituisce semplicemente un proxy non inizializzato e non colpisce effettivamente il database finché non si richiama un metodo del proxy. Ciò è utile se si desidera creare un'associazione a un oggetto senza caricarlo effettivamente dal database. Consente inoltre di caricare più istanze come batch se è definita la dimensione del batch per il mapping della classe.

Per favore aiutami a capire questo spiegando il significato delle parti evidenziate sopra in grassetto .


Answers

Questo è simile al lazy-loading delle associazioni, ma potrebbe essere visto come più "pigro-creare".

Un proxy è una sottoclasse implementata in fase di runtime. Hibernate crea un proxy (una sottoclasse della classe che viene recuperata) invece di interrogare direttamente il database, e questo proxy caricherà l'oggetto "reale" dal database ogni volta che viene chiamato uno dei suoi metodi.

Il secondo testo evidenziato spiega che se si chiama load() su più istanze, è possibile recuperarle come batch e in questo modo ridurre i roundtrip al database.

Questa è anche la differenza tra load () e get (), carica il tipo di lazy-load dell'oggetto, mentre recupera l'oggetto dal database subito


I proxy sono classi generate dinamicamente da Hibernate per aiutare con il caricamento lento. Ad esempio, se si ha una classe Cat , Hibernate genererà una classe proxy che estende Cat .

Se ottieni un'istanza non inizializzata di questo proxy, in sostanza tutti i suoi campi saranno nulli tranne l'ID perché Hibernate non ha ancora colpito il database. Ora la prima volta che chiamerai un metodo su questo proxy, realizzerà che non è inizializzato e interrogherà il database per caricarne gli attributi. Ciò è possibile perché la classe generata dinamicamente sovrascrive i metodi della classe base e aggiunge questo controllo inizializzato / non inizializzato.

Supponiamo ora che la tua classe Cat non sia un proxy e che abbia un'associazione father , quando carichi un oggetto Cat, Hibernate dovrà caricare tutti gli attributi. Quindi, se si carica un oggetto Cat , Hibernate dovrà caricare anche suo padre e il padre del padre e così via. Utilizzando i proxy abilitare Hibernate per caricare solo le istanze richieste.

Cat cat1 = (Cat) session.load(1);
Cat cat2 = (Cat) session.load(2);
Cat cat3 = (Cat) session.load(3);

cat1.meow(); // this will cause Hibernate to run a query to load cat1's data
cat2.meow(); // this will cause Hibernate to run a query to load cat2's data

// After this cat3 is still an uninitiated proxy because it has not been used

batch-size è un'altra caratteristica di Hibernate che, nella maggior parte dei casi, aiuta a gestire il caricamento lento. Fondamentalmente l'idea è che Hibernate tenga traccia dei proxy non inizializzati e quando una delle necessità debba essere inizializzata, verrà eseguita un'unica query per caricare fino a proxy di batch-size (invece di un solo proxy / query)

Cat cat1 = (Cat) session.load(1);
Cat cat2 = (Cat) session.load(2);

cat1.meow(); // if batch-size >= 2, cat1 and cat2 will be loaded in a single query
cat2.meow(); // no query will be executed here

Come spiegato nel mio libro, Persistenza Java ad alte prestazioni , il Proibito Hibernate viene utilizzato per sostituire un'entità reale POJO (Plain Old Java Object).

La classe Proxy viene generata in fase di runtime e estende la classe di entità originale.

Hibernate utilizza oggetti proxy per le entità è per consentire il caricamento lazy .

Quando si accede alle proprietà di base sul Proxy, si limita a delegare la chiamata all'entità originale.

Ogni List , Set , tipo di Map nella classe entità viene sostituito da PersistentList , PersistentSet , PersistentMap . Queste classi sono responsabili dell'intercettazione di una chiamata a una raccolta non inizializzata.

Il proxy non rilascia alcuna istruzione SQL. Semplicemente innesca un InitializeCollectionEvent , che viene gestito dal listener associato, che conosce la query di inizializzazione da emettere (dipende dal piano fetch configurato).





java hibernate proxy