Mysql
 sql >> Base de données >  >> RDS >> Mysql

LazyInitializationException essayant d'obtenir une instance initialisée paresseuse

Tout d'abord, vous devez comprendre que la racine du problème n'est pas une transaction. Nous avons une transaction et un contexte persistant (session). Avec @Transactional L'annotation Spring crée une transaction et ouvre un contexte persistant. Une fois la méthode invoquée, un contexte persistant est fermé.

Lorsque vous appelez un user.getUserAccount() vous avez une classe proxy qui encapsule UserAccount (si vous ne chargez pas UserAccount avec User ). Ainsi, lorsqu'un contexte persistant est fermé, vous avez une LazyInitializationException lors de l'appel de n'importe quelle méthode de UserAccount , par exemple user.getUserAccount().toString() .

@Transactional travaillant uniquement sur le userService niveau, dans votre cas. Pour obtenir @Transactional travail, il ne suffit pas de mettre le @Transactional annotation sur une méthode. Vous devez obtenir un objet d'une classe avec la méthode à partir d'un Spring Context . Donc, pour mettre à jour l'argent, vous pouvez utiliser une autre méthode de service, par exemple updateMoney(userId, amount) .

Si vous souhaitez utiliser @Transactional sur la méthode du contrôleur, vous devez obtenir un contrôleur à partir du Spring Context . Et Spring devrait comprendre qu'il devrait envelopper chaque @Transactional avec une méthode spéciale pour ouvrir et fermer un contexte persistant. Une autre méthode consiste à utiliser le modèle Session Per Request Anti. Vous devrez ajouter un filtre HTTP spécial.

https://vladmihalcea.com/the-open-session- in-view-anti-pattern/