Mysql
 sql >> Database >  >> RDS >> Mysql

LazyInitializationException tenta di ottenere un'istanza inizializzata pigra

In primo luogo, dovresti capire che la radice del problema non è una transazione. Abbiamo una transazione e un contesto persistente (sessione). Con @Transactional annotation Spring crea una transazione e apre un contesto persistente. Dopo che il metodo è stato invocato, un contesto persistente viene chiuso.

Quando chiami un user.getUserAccount() hai una classe proxy che racchiude UserAccount (se non carichi UserAccount con User ). Quindi, quando un contesto persistente viene chiuso, hai una LazyInitializationException durante la chiamata di qualsiasi metodo di UserAccount , ad esempio user.getUserAccount().toString() .

@Transactional lavorando solo su userService livello, nel tuo caso. Per ottenere @Transactional lavoro, non basta mettere il @Transactional annotazione su un metodo. Devi ottenere un oggetto di una classe con il metodo da un Spring Context . Quindi, per aggiornare il denaro puoi utilizzare un altro metodo di servizio, ad esempio updateMoney(userId, amount) .

Se vuoi usare @Transactional sul metodo controller devi ottenere un controller da Spring Context . E Spring dovrebbe capire che dovrebbe racchiudere ogni @Transactional metodo con un metodo speciale per aprire e chiudere un contesto persistente. Un altro modo è utilizzare il pattern Session Per Request Anti. Dovrai aggiungere uno speciale filtro HTTP.

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