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/