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-loaded
relazioni.
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
Model
oggetti 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-loaded
relazioni nella progettazione dell'applicazione?
(Oh, e scusa per WoT )