J'ai tendance à utiliser Hibernate en combinaison avec Printemps et ses capacités de démarcation déclarative des transactions (par ex, @Transactional ).
Comme nous le savons tous, Hibernate essaie d'être aussi non invasif et comme transparent que possible, mais cela prouve un peu plus difficile lors de l'utilisation lazy-loaded
relations.
Je vois un certain nombre d'alternatives de conception avec différents niveaux de transparence.
- Faire en sorte que les relations ne soient pas chargées paresseusement (par ex,
fetchType=FetchType.EAGER)
- Cela vicie l'idée même du chargement paresseux
- Initialiser les collections en utilisant
Hibernate.initialize(proxyObj);
- Cela implique un couplage relativement élevé avec le DAO.
- Bien que nous puissions définir une interface avec
initialize
les autres implémentations ne sont pas garanties de fournir un équivalent.
- Ajout d'un comportement de transaction au système persistant
Model
eux-mêmes (en utilisant soit proxy dynamique o@Transactional
)- Je n'ai pas essayé l'approche du proxy dynamique, bien que je n'aie jamais réussi à faire fonctionner @Transactional sur les objets persistants eux-mêmes. C'est probablement dû au fait qu'Hibernate fonctionne avec un proxy.
- Perte de contrôle au moment où les transactions ont lieu
- Fournir une API paresseuse/non paresseuse, par ex,
loadData()
yloadDataWithDeps()
- Oblige l'application à savoir quand utiliser telle ou telle routine, ce qui constitue un couplage étroit.
- Dépassement de méthode,
loadDataWithA()
, ....,loadDataWithX()
- Forcer la recherche de dépendances, par exemple en fournissant seulement
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 d'extraire chaque objet d'une collection un par un si les frais de traitement entre les transactions sont importants.
- Nécessite beaucoup de routines non orientées objet, par exemple,
- Faire une partie de la application @Transactional au lieu de la seule DAO
- Considérations possibles sur les transactions imbriquées
- Nécessite des routines adaptées à la gestion des transactions (par exemple, suffisamment petites)
- Faible impact programmatique, bien qu'il puisse entraîner des transactions importantes.
- Fournir à la DAO des données dynamiques Récupérer des profils par exemple,
loadData(id, fetchProfile);
- Les applications doivent savoir quel profil utiliser lorsque
- Type d'opérations de l'AoP, par exemple, intercepter des opérations et effectuer des transactions si nécessaire.
- Nécessite la manipulation du code d'octet ou l'utilisation d'un proxy.
- Perte de contrôle lors de l'exécution 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 de lazy-loaded
dans la conception de votre application ?
(Oh, et désolé pour WoT )