@RestController methods seem to be Transactional by default, Why?
The answer of @dunni is absolutely brilliant and works. In my case it penalized performance, in the call from a @Controller to a method of an @Service with @Transactional processing read-only JPA operations, on the other hand, calling the same method from a @WebServlet processed it twice as fast. But setting spring.jpa.open-in-view=false from @Controller processed just as fast than from @WebServlet.
But in addition in this sense you can do the following unitarily and works the same annotating the method called from @Controller with @Transactional in this way, example:
@GetMapping("/test")
@Transactional(propagation = Propagation.NEVER, readOnly = true)
public void test()
In addition to MirMasej answers, there is one more thing: Spring Boot will automatically register an OpenEntityManagerInViewInterceptor
when the following conditions are true:
- you have a web application
- you use JPA
Both conditions are true in your case. This interceptor holds the entity manager open for the whole duration of a request. The auto configuration occurs in the class JpaBaseConfiguration
.
If you don't want that behaviour, you can add the following property to your application.properties file:
spring.jpa.open-in-view=false
Btw. this behaviour is completely independent of transactions, it's only related to the lifecycle of the entity manager. You can still have two separate transactions and no LazyInitializationException, if both transactions have the same underlying entity manager instance.