Mysql
 sql >> Datenbank >  >> RDS >> Mysql

LazyInitializationException versucht, eine verzögert initialisierte Instanz abzurufen

Zunächst sollten Sie verstehen, dass die Ursache des Problems keine Transaktion ist. Wir haben eine Transaktion und einen dauerhaften Kontext (Sitzung). Mit @Transactional Anmerkung Spring erstellt eine Transaktion und öffnet einen persistenten Kontext. Nachdem die Methode aufgerufen wurde, wird ein persistenter Kontext geschlossen.

Wenn Sie ein user.getUserAccount() aufrufen Sie haben eine Proxy-Klasse, die UserAccount umschließt (wenn Sie UserAccount nicht laden mit User ). Wenn also ein persistenter Kontext geschlossen wird, haben Sie eine LazyInitializationException während des Aufrufs einer beliebigen Methode von UserAccount , zum Beispiel user.getUserAccount().toString() .

@Transactional arbeitet nur auf dem userService Ebene, in Ihrem Fall. Um @Transactional zu erhalten funktioniert, reicht es nicht aus, @Transactional zu setzen Anmerkung zu einer Methode. Sie müssen ein Objekt einer Klasse mit der Methode aus einem Spring Context erhalten . Um Geld zu aktualisieren, können Sie also eine andere Servicemethode verwenden, zum Beispiel updateMoney(userId, amount) .

Wenn Sie @Transactional verwenden möchten Bei der Controller-Methode müssen Sie einen Controller aus Spring Context abrufen . Und Spring sollte verstehen, dass es jeden @Transactional umschließen sollte -Methode mit einer speziellen Methode zum Öffnen und Schließen eines persistenten Kontexts. Eine andere Möglichkeit besteht darin, das Session-Per-Request-Anti-Pattern zu verwenden. Sie müssen einen speziellen HTTP-Filter hinzufügen.

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