Why Open Session in View Can Kill Your Spring Boot Performance (And How to Fix It)

The article explains what Open Session in View (OSIV) is, why keeping a Hibernate Session open for the whole request can silently cause massive N+1 query problems in Spring Boot REST APIs, and provides a concrete example and step‑by‑step solution using explicit fetch joins and disabling OSIV.

Java Architect Handbook
Java Architect Handbook
Java Architect Handbook
Why Open Session in View Can Kill Your Spring Boot Performance (And How to Fix It)

What is Open Session in View (OSIV)?

OSIV is a pattern (often regarded as an anti‑pattern) that keeps the Hibernate Session open for the whole HTTP request. After the transaction and service method have returned, the persistence context remains alive, so lazy‑loaded associations can still be fetched during view rendering or JSON serialization.

Why OSIV is risky

Because the session stays open, SQL statements may be executed at unpredictable moments (e.g., while serialising a response). This hides the true cost of lazy loading and can cause severe performance degradation, especially in REST‑API + JSON architectures.

Concrete N+1 example

Consider a typical e‑commerce domain model:

Customer (1) ── (n) PurchaseOrder (1) ── (n) OrderItem (n) ── (1) Product

Relevant JPA entities (simplified):

@Entity
public class Customer {
    @OneToMany(mappedBy = "customer")
    private List<PurchaseOrder> orders = new ArrayList<>();
}

@Entity
public class PurchaseOrder {
    @ManyToOne
    private Customer customer;
    @OneToMany
    @JoinColumn(name = "purchase_order_id")
    private List<OrderItem> items = new ArrayList<>();
}

@Entity
public class OrderItem {
    @ManyToOne(fetch = FetchType.LAZY)
    private Product product;
}

REST controller using the default repository method:

@GetMapping("/osiv")
public List<PurchaseOrderDTO> getOrders() {
    var orders = purchaseOrderRepository.findAll(); // returns 100 orders
    return orders.stream()
                 .map(o -> modelMapper.map(o, PurchaseOrderDTO.class))
                 .toList();
}

With OSIV enabled, the following queries are triggered during DTO mapping: order.customer → 100 additional SELECTs order.items → 100 additional SELECTs item.product → 500 additional SELECTs (5 products per order)

Total SQL statements:

1 (orders) + 100 (customers) + 100 (order_items) + 500 (products) = 701

. The request therefore performs more than 700 database round‑trips.

Correct approach

Explicitly fetch the required associations in a single query and disable OSIV so that any accidental lazy access after the transaction fails fast with LazyInitializationException.

@Query("""
    SELECT o FROM PurchaseOrder o
    JOIN FETCH o.items i
    JOIN FETCH o.customer
    JOIN FETCH i.product
""")
List<PurchaseOrder> findAllFetchRelations();

This JPQL generates one SQL statement:

SELECT o.*, i.*, c.*, p.*
FROM purchase_order o
JOIN order_item i ON i.purchase_order_id = o.id
JOIN customer c ON c.id = o.customer_id
JOIN product p ON p.id = i.product_id;

Disable OSIV in application.properties (or application.yml) to enforce the fetch strategy:

spring.jpa.open-in-view=false

Result

Only a single SQL query is executed regardless of the number of orders, items or products, eliminating the N+1 problem and making the performance predictable.

Conclusion

OSIV masks underlying architectural issues by allowing lazy loading after the transaction has completed. In modern REST APIs the priority should be on explicit fetch plans and controllable database access. Disabling OSIV and using JOIN FETCH (or EntityGraph, DTO projections, etc.) yields deterministic and efficient queries.

PerformanceSpring BootHibernatejpaN+1 QueryOSIV
Java Architect Handbook
Written by

Java Architect Handbook

Focused on Java interview questions and practical article sharing, covering algorithms, databases, Spring Boot, microservices, high concurrency, JVM, Docker containers, and ELK-related knowledge. Looking forward to progressing together with you.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.