Mise en veille prolongée problème d'initialisation paresseuse: LazyInitializationException: Échec de l'initialisation paresseusement une collection de rôle
-
13-09-2019 - |
Question
Je veux gérer une opération dans ma couche de persistance, Mais quand je tente d'aller chercher les résultats paresseusement je reçois cette erreur:
org.hibernate.LazyInitializationException: Échec de l'initialisation paresseusement une collection de rôle
Puis-je utiliser LockMode ou tout autre moyen de résoudre ce problème? Peut trouver un un objet par son id sans transaction?
La solution
Votre problème est que la session Hibernate est déjà fermé lorsque vous essayez d'accéder au contenu. Mise en veille prolongée ne peut pas charger le contenu sans une session. Il y a généralement deux façons d'atténuer ce problème:
-
Ne fermez pas la session jusqu'à ce que vous avez terminé avec la page. Ce modèle est appelé « session en vue » et peut par exemple être mis en œuvre avec un filtre de servlet.
-
Initialiser tout le contenu que vous aurez besoin avant de fermer la session. Si vous voulez initialiser l'objet entier, vous pouvez utiliser Hibernate.initialize (objet).
modifier. Vous ne pouvez rien faire en dehors d'une transaction dans Hibernate
Autres conseils
Vous pouvez également consulter la solution officielle de mise en veille prolongée à http://www.hibernate.org/43.html
En général, le problème est que l'un des attributs de l'objet est mollement chargé. Une chose que vous pouvez faire est de l'avoir pré-chargé dans votre requête:
de la vente de vente où sale.date>: startDate gauche join fetch sale.product
Cela précharger l'objet sale.product.
ce site a plus d'informations: http://www.javalobby.org/ articles / mise en veille prolongée-query-101 / .
-Dave
Il y a plusieurs façons de propriétés prélecture, de sorte qu'ils sont là après session est fermée:
- Il suffit d'appeler getter approprié. Après champ est tiré par les cheveux dans le haricot est là après session est fermée.
- Utiliser l'attribut approprié dans le descripteur de haricot dans JPA vous utiliseriez
@OneToMany(fetch = FetchType.EAGER)
, mais il existe des moyens de mise en veille prolongée semblable à le faire. - Vous pouvez initialiser champ dans la requête HQL (je ne sais pas si cela fonctionne dans HQL, mais je pense qu'il ne), chercher mot-clé
FETCH INTO
.
Ou tout simplement utiliser un autre ORM ... comme Ebean ORM où le chargement paresseux fonctionne:)