By default, Spring Boot uses an OpenEntityManagerInViewInterceptor which “binds a JPA EntityManager to the thread for the entire processing of the request […] to allow for lazy loading in web views despite the original transactions already being completed”.
In other words, in every @Controller
/@RestController
action, instead of throwing a LazyInitializationException
when you forget to fetch a lazy-loaded property, Spring will now fetch the property outside of the original transaction. The pattern (or antipattern) is called Open Session In View (OSIV) and, while it sounds fairly useful, is not a good choice for production environments.
To disable OSIV, add the following line to your application.properties
file:
spring.jpa.open-in-view=false
I came across the problem of missing LazyInitializationExceptions
at work when debugging an unrelated problem related to an object repository. I’ve noticed that I was getting way more information than I was asking for – the repository seemed to be fetching all of the object’s properties, rather than just the ones with Fetchtype.EAGER
that it was supposed to. After hours of looking through the code, I finally arrived at a DTO builder, way outside of the scope of the database transaction. It seemed that the calls to getters of the original object in the builder were somehow triggering calls to the database, instead of throwing a LazyInitializationException
.
I believe that the above story is a good reason to disable OSIV – it violates the Principle of Least Astonishment. If I forget to fetch a lazy-loaded property and then try to access it, I expect an exception to be thrown, not for the property to be magically appended to the object. It is, however, not the only reason – OSIV seems to be a performance headache waiting to happen! As a developer, you usually want to have a tight grip on how your objects are obtained from the database – sometimes to the point of painstakingly fine-tuning the smallest of queries. If your object leaves the database service in an incomplete state, it’s usually something you want to know about. In cases like this, OSIV seems like a poor-quality band-aid hiding a bigger problem (the problem being improper database queries).
For further reading (and more arguments against OSIV), I recommend Vlad Mihalcea’s article on the Open Session in View Antipattern.
Thank’s!, I agree with you;
PS: and wtf man? this AntiPattern as a default behaviour in SpringBoot ?
Tens years ago we had read so many articles about how bad is this practive;
[…] View Reddit by vladmihalceacom – View Source […]
Thanks and it is excellent explanation. In my case i am still facing a puzzle
i was using spring boot v 2.2 and we never face JDBC connection pool issues ( Hikari Pool)
we switched to spring boot 2.4 and we suddenly with same code started facing JDBC connection issues which went off post we used OSIV in our configuration.