Tendo a usare Hibernate in combinazione con il framework Spring e le sue capacità di demarcazione dichiarativa delle transazioni (ad esempio, @Transactional ).
Come tutti sappiamo, l'ibernazione cerca di essere il più non invasivo e trasparente possibile, tuttavia questo si rivela un po 'più impegnativo quando si impiegano lazy-loadedrelazioni.
Vedo una serie di alternative di design con diversi livelli di trasparenza.
- Crea relazioni non pigre (p. Es.,
fetchType=FetchType.EAGER)- Questo vioalizza l'intera idea di caricamento lento.
- Inizializza le raccolte utilizzando
Hibernate.initialize(proxyObj);- Ciò implica un accoppiamento relativamente alto al DAO
- Sebbene possiamo definire un'interfaccia con
initialize, non è garantito che altre implementazioni forniscano alcun equivalente.
- Aggiungi il comportamento della transazione agli
Modeloggetti persistenti stessi (utilizzando il proxy dinamico o@Transactional)- Non ho provato l'approccio proxy dinamico, anche se non mi è mai sembrato di far funzionare @Transactional sugli oggetti persistenti stessi. Probabilmente a causa di tale ibernazione è un'operazione su un proxy con cui stare.
- Perdita di controllo quando le transazioni sono effettivamente in corso
- Fornisci API pigra / non pigra, ad esempio
loadData()eloadDataWithDeps()- Forza l'applicazione a sapere quando utilizzare quale routine, ancora una volta accoppiamento stretto
- Metodo overflow,,
loadDataWithA()....,loadDataWithX()
- Forza la ricerca delle dipendenze, ad esempio fornendo solo
byId()operazioni- Richiede molte routine non orientate agli oggetti, ad esempio
findZzzById(zid), e quindigetYyyIds(zid)invece diz.getY() - Può essere utile recuperare ogni oggetto in una raccolta uno per uno se c'è un grande sovraccarico di elaborazione tra le transazioni.
- Richiede molte routine non orientate agli oggetti, ad esempio
- Fai parte dell'applicazione @Transactional invece del solo DAO
- Possibili considerazioni sulle transazioni annidate
- Richiede routine adattate per la gestione delle transazioni (ad esempio, sufficientemente piccole)
- Piccolo impatto programmatico, anche se potrebbe comportare transazioni di grandi dimensioni
- Fornire al DAO profili di recupero dinamici , ad es.
loadData(id, fetchProfile);- Le applicazioni devono sapere quale profilo utilizzare e quando
- Tipo di transazione AoP, ad esempio, intercetta le operazioni ed esegue le transazioni quando necessario
- Richiede la manipolazione del codice byte o l'utilizzo del proxy
- Perdita di controllo durante l'esecuzione delle transazioni
- Magia nera, come sempre :)
Ho perso qualche opzione?
Qual è il tuo approccio preferito quando cerchi di ridurre al minimo l'impatto delle lazy-loadedrelazioni nella progettazione dell'applicazione?
(Oh, e scusa per WoT )