2013-01-16 18 views
7

Correggimi se questo è un duplicato esatto, so che questo argomento viene discusso spesso ma non riesco a trovare una risposta definitiva.MVC con caricamento lento

La domanda:

Qual è la migliore soluzione pratica per la manipolazione di oggetti Hibernate in una webapp MVC?

I dettagli:

Sto usando Hibernate e voglio sfruttare lazy loading, ove possibile.
Sto lavorando in una webapp in stile MVC.
Odio ricevere le eccezioni di inizializzazione del carico pigro.
Detesto dover ricollegare gli oggetti Hibernate tra le transazioni.

Le opzioni:

  1. carico Eager tutto
    • risolve il problema di inizializzazione pigra, ma rende le mie domande più grande
  2. usare un po 'Open Session View' concetto
    • Mi piace la sua semplicità
    • oggetti devono ancora essere riattaccato, e in una configurazione AJAXy, abbastanza frequentemente
    • si apre una sessione per ogni richiesta
  3. articoli 'touch' ho bisogno prima di lasciare la transazione
    • Sembra fragile a meglio .. e noioso
  4. Crea diversi oggetti, semplificate, villino quindi la vista non vede mai reale Hibernate oggetti
    • Th ese potrebbe essere più semplice di oggetti pieni Hibernate quindi non è come un carico desiderosi completa del modello
    • ho sentito questa consigliato in luoghi a, ma sembra proprio come più responsabilità/code/lavoro
  5. Aprire una sessione quando mai voglio interagire con gli oggetti di Hibernate.
    • Questo può essere racchiuso in un livello Spring Service piuttosto bene, ma a volte sembra eccessivo. Ad esempio: Voglio hibernateObject.getRelatedObjects() ma bisogno di dire qualcosa di simile springService.getRelatedObjects(hibernateObject)

mi sto perdendo qualcosa?
Ho pensato troppo alle cose?
Ho sottovalutato le cose?

PS:

Per un framework web che sto utilizzando ZK ma non vuole veramente una risposta specifica ZK.
Anche io sto usando Spring e sono cool con una risposta specifica di Spring perché è così onnipresente.

risposta

5

Usa 4-ish - Non utilizzare la sessione aperta in vista, non avere le entità di ibernazione aperte fino alla vista, invece i trasformatori traducono tra le entità di ibernazione e gli oggetti di dominio o "visualizza bean" dipende da come lo vuoi lavorare.

Penso che le entità di Hibernate siano solo una strategia di persistenza, non un modello di dominio o una rappresentazione dell'interfaccia utente.

+0

Acclamazioni Bedwyr, penso che mi prendo questo approccio. È un po 'più codice, ma la separazione tra vista e modello dovrebbe valerne la pena. –

+0

Sono d'accordo con questa risposta e lo ho svalutato, voglio solo aggiungere un pezzo di codice che potresti trovare utile. Ecco una copiatrice a profondità variabile, dipende da Spring ma è più leggera di una soluzione di mappatura completa come Dozer. https://gist.github.com/thinkbigthings/5488327 – Jay

+0

Anche qui c'è un unproxer Hibernate: https: // gist.github.com/thinkbigthings/5141813 – Jay

1

La combinazione del livello di presentazione con il livello di accesso ai dati è un problema di progettazione.

La tua vista dovrebbe accedere al modello attraverso un controller, ma usando gli oggetti di ibernazione direttamente stai mescolando i livelli. L'accesso ai dati IMO dovrebbe essere un altro livello sotto il modello. Anche se le tue entità sono annotate o definite in un xml, sono separate dal modello in sé.

Introdurre una facciata o un gestore che incapsula la logica di Hibernate e esponila attraverso un contratto di servizio per i controllori, restituendo oggetti significativi che rappresentano tali entità. Se del caso, mi piacerebbe andare per l'opzione 4.

+0

Grazie Gamb. È un po 'più di codice e lavoro, ma penso che renderà un'applicazione più pulita, più testabile. Se potessi accettare sia il tuo che quello di @ Bedwyr, ne sceglierei uno a caso. –

+0

@SeanConnolly Nessun problema, felice di essere di aiuto :) – Gamb

3

Ci sono tre modi:

Usa ansiosi prendere carico per i vostri attributi: può essere un problema se si dispone di un grande datatable.

Utilizzare un filtro chiamato OpenSessionInView: questo filtro non mancherà di tenere la sessione aperta fino al pieno carico della tua pagina web. Se in questo carico è stato richiesto un oggetto di ibernazione, la sessione verrà aperta ed eviterà l'eccezione di caricamento lento.

utente VO (valueble Objects): nell'applicazione, avranno 2 tipi di oggetti. Un oggetto da passare tra la persistenza e il livello aziendale e un oggetto per il tuo livello di vista. Ad esempio, UserVO e UserModel. Verrà utilizzato un vo per trasportare le informazioni tra vista e livello aziendale. Nella tua implementazione aziendale, userai il vo per riempire l'oggetto del modello per inviarlo al tuo livello di persistenza. Usando questo modello, non avrai più un'eccezione di carico pigro perché tutte le informazioni necessarie saranno riempite nel tuo oggetto vo quando è necessario.

Alcune referenze:
OpenSessionInView
Eager Fetching Load
Hibernate Performance tips

Problemi correlati