Първо, трябва да разберете, че коренът на проблема не е транзакция. Имаме транзакция и постоянен контекст (сесия). С @Transactional
анотация Spring създава транзакция и отваря постоянен контекст. След като методът бъде извикан, постоянният контекст се затваря.
Когато извикате user.getUserAccount()
имате прокси клас, който обвива UserAccount
(ако не заредите UserAccount
с User
). Така че, когато постоянен контекст е затворен, имате LazyInitializationException
по време на извикване на който и да е метод на UserAccount
, например user.getUserAccount().toString()
.
@Transactional
работи само на userService
ниво във вашия случай. За да получите @Transactional
работа, не е достатъчно да поставите @Transactional
анотация върху метод. Трябва да получите обект на клас с метода от Spring Context
. Така че, за да актуализирате парите, можете да използвате друг метод на услугата, например updateMoney(userId, amount)
.
Ако искате да използвате @Transactional
на метода на контролера трябва да получите контролер от Spring Context
. И Spring трябва да разбере, че трябва да обвие всеки @Transactional
метод със специален метод за отваряне и затваряне на постоянен контекст. Друг начин е да използвате сесия на заявка анти шаблон. Ще трябва да добавите специален HTTP филтър.
https://vladmihalcea.com/the-open-session- in-view-anti-pattern/