Why Open Session in View (OSIV) Can Kill Your Spring Boot Performance

Spring Boot’s default Open Session in View (OSIV) keeps Hibernate sessions open throughout the request, silently triggering lazy‑loaded queries during JSON serialization, leading to N+1 problems and massive DB load under load, but disabling it and using explicit fetch joins restores performance.

Architecture Digest
Architecture Digest
Architecture Digest
Why Open Session in View (OSIV) Can Kill Your Spring Boot Performance

What is Open Session in View (OSIV)?

OSIV is a design pattern – often considered an anti‑pattern today – that keeps the Hibernate Session open for the entire HTTP request lifecycle. After the transaction has finished and the service method has returned, the persistence context remains alive, allowing lazy‑loaded entities to be fetched during JSON serialization or view rendering.

Why OSIV Is Dangerous in Modern REST APIs

OSIV does not hold a database connection continuously, but it permits SQL execution at any unpredictable moment. In traditional server‑side rendered pages (JSP, Thymeleaf) this was convenient, but with REST APIs that return JSON the cost is high. When OSIV is enabled (the default in Spring Boot), lazy loading works silently, the API returns correct data, and the performance problem is hidden until high concurrency or large data volumes cause the database CPU to spike.

Real‑World N+1 Query Example

Typical e‑commerce model:

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

JPA entities (simplified):

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

@Entity
public class PurchaseOrder {
    @ManyToOne(cascade = CascadeType.ALL, optional = false)
    private Customer customer;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "purchase_order_id")
    private List<OrderItem> items = new ArrayList<>();
}

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

REST controller:

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

Repository:

public interface PurchaseOrderRepository extends JpaRepository<PurchaseOrder, Long> {}

Execution flow when /osiv is called:

findAll(): 1 SQL to fetch orders.

ModelMapper traverses the object graph.

Lazy loading triggers: order.customer → N SQL order.items → N SQL item.product → N×M SQL

Assuming 100 orders, each with 5 products, the total SQL statements become 701, i.e., more than 700 database round‑trips for a single request.

Correct Approach

Explicitly fetch the needed associations with a single query:

@Query("""
    select o from PurchaseOrder o
    join fetch o.items i
    join fetch o.customer
    join fetch i.product
""")
List<PurchaseOrder> findAllFetchRelations();

This generates one SQL statement joining all tables, dramatically reducing database load.

Disable OSIV in application.properties:

spring.jpa.open-in-view=false

Summary

OSIV solves the superficial problem of lazy loading in view rendering but hides a deeper architectural flaw. In modern REST API architectures, performance and control must take precedence over the convenience OSIV provides. Disabling OSIV and using explicit fetch joins is the recommended practice.

Reference: https://martinelli.ch/the-hidden-performance-killer-understanding-open-session-in-view-in-spring-boot

PerformanceSpring BootHibernatejpaN+1 QueryOSIV
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

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.