J'ai tendance à utiliser Hibernate en combinaison avec le framework Spring et ses capacités de démarcation de transaction déclarative (par exemple, @Transactional ).
Comme nous le savons tous, la mise en veille prolongée essaie d'être aussi non invasive et transparente que possible, mais cela s'avère un peu plus difficile lors de l'utilisation de lazy-loaded
relations.
Je vois un certain nombre d'alternatives de conception avec différents niveaux de transparence.
- Faites des relations non paresseuses (par exemple,
fetchType=FetchType.EAGER)
- Cela vioalite toute l'idée du chargement paresseux.
- Initialiser les collections en utilisant
Hibernate.initialize(proxyObj);
- Cela implique un couplage relativement élevé au DAO
- Bien que nous puissions définir une interface avec
initialize
, les autres implémentations ne sont pas garanties de fournir un équivalent.
- Ajouter un comportement de transaction aux
Model
objets persistants eux-mêmes (à l'aide d' un proxy dynamique ou@Transactional
)- Je n'ai pas essayé l'approche proxy dynamique, même si je n'ai jamais semblé faire fonctionner @Transactional sur les objets persistants eux-mêmes. Probablement à cause de cette mise en veille prolongée est l'opération sur un proxy avec lequel bein.
- Perte de contrôle lorsque des transactions ont effectivement lieu
- Fournir à la fois une API paresseuse / non paresseuse, par exemple,
loadData()
etloadDataWithDeps()
- Force l'application à savoir quand utiliser quelle routine, encore une fois couplage serré
- Débordement de méthode,,
loadDataWithA()
....,loadDataWithX()
- Forcer la recherche de dépendances, par exemple en fournissant uniquement des
byId()
opérations- Nécessite beaucoup de routines non orientées objet, par exemple
findZzzById(zid)
, et ensuitegetYyyIds(zid)
au lieu dez.getY()
- Il peut être utile de récupérer chaque objet d'une collection un par un s'il y a une surcharge de traitement importante entre les transactions.
- Nécessite beaucoup de routines non orientées objet, par exemple
- Faire partie de l' application @Transactional au lieu de seulement le DAO
- Considérations possibles sur les transactions imbriquées
- Nécessite des routines adaptées à la gestion des transactions (par exemple, suffisamment petites)
- Petit impact programmatique, bien qu'il puisse entraîner de grosses transactions
- Fournir au DAO des profils de récupération dynamiques , par exemple
loadData(id, fetchProfile);
- Les applications doivent savoir quel profil utiliser quand
- Type de transactions AoP, par exemple, intercepter des opérations et effectuer des transactions si nécessaire
- Nécessite une manipulation de code d'octet ou l'utilisation d'un proxy
- Perte de contrôle lors des transactions
- Magie noire, comme toujours :)
Ai-je manqué une option?
Quelle est votre approche préférée lorsque vous essayez de minimiser l'impact des lazy-loaded
relations dans la conception de votre application?
(Oh, et désolé pour WoT )