Open Session in View (OSIV) in Spring - Enable or Disable?
Author
Marcus HeldIf you are working with Spring Boot and Hibernate, you have undoubtedly come across the term “Open Session in View” (OSIV) or its corresponding property open-in-view
. But what exactly does this option do, and how does it affect your interaction with the database? Should you enable or disable it? In this article, we delve deep into the topic and shed light on its functionality and differences compared to other approaches.
What is OSIV?
Open Session in View is a pattern that is enabled by default in Spring Boot and can be disabled through a specific option. You have probably seen this warning before:
2023-08-29T17:31:48.014+02:00 WARN 65701 --- [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
OSIV ensures that the Hibernate Session remains open for the entire duration of an HTTP request. This may sound unremarkable at first, but it has far-reaching implications for how you deal with Lazy Associations and Entities in your code.
// A typical lazy-loaded attribute in an entity
@Entity
public class User {
@Id
private UUID id = UUID.randomUUID();
@OneToMany(fetch = FetchType.LAZY)
private List<Order> orders;
}
Without OSIV, accessing user.getOrders()
outside of a transaction would result in a LazyInitializationException
. With OSIV, the session remains open, allowing you to access the orders. They are loaded lazily, as configured.
OSIV is a Servlet Filter
Spring implements OSIV in the OpenSessionInViewFilter
class. This class is an implementation of the OncePerRequestFilter
, which—as the name suggests—is executed exactly once per request. Within it, the Hibernate Session is opened for the duration of the request and closed afterward.
// Pseudocode for the OSIV filter
public class OpenSessionInViewFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
Session session = sessionFactory.openSession();
try {
// Here the request is processed
chain.doFilter(req, res);
} finally {
session.close();
}
}
}
OSIV and Transactions
As you may have noticed in the pseudocode above, no transaction is opened with OSIV. We only have a Hibernate Session. But what does that actually mean?
The Hibernate Session is a lightweight container that manages the connection to the database and the lifecycle of persistent objects. CRUD operations (Create, Read, Update, Delete) are carried out through a session.
Without a transaction, it is possible to work with inconsistent data. If another session modifies the same entities during processing, this cannot be detected. As a result, you can create hard-to-trace bugs and states in your application.
Should I Disable OSIV?
Once you have learned how transactions work in Spring , what states entities can have and what consequences result from them : yes.
OSIV makes it easy for beginners to get started with Spring. They don’t have to deal with the details of JPA and Hibernate. They don’t constantly experience LazyInitializationException
and get frustrated. However, this simplification makes it more likely that entities in the application will be passed across transaction boundaries. What still works on the developer machine fails under load.
Disable OSIV and Use @Transactional
To disable OSIV, add the following line to your application.properties
:
spring.jpa.open-in-view=false
Since you are no longer able to fetch relations lazily, you should, in the simplest case, wrap your controller methods with @Transactional
. This ensures that each request is atomic and is either fully applied or not at all. And since we implicitly also open a Hibernate Session, we can fetch our relations lazily.
But What About Performance? (panic!)
Don’t worry. In 99% of all cases, this strategy will be “good enough.” In all other cases, you will need individual solutions. Perhaps the request should be executed asynchronously? Or maybe you can split it into multiple transactions. Always keep an eye on your performance and react as soon as you see corresponding symptoms.
In conclusion, I recommend reading this GitHub discussion from the Spring project: Log a warning on startup when spring.jpa.open-in-view is enabled but user has not explicitly opted in . There are many good arguments for and against OSIV. Familiarize yourself with them and make your choice for your project and your context.