Skip to content

ercansormaz/spring-osiv-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OSIV Demo — Open Session in View / Spring Boot Performance Test

Project Purpose

This project demonstrates the behavior of Spring Boot's Open Session in View (OSIV) feature with spring.jpa.open-in-view=true and false.
It aims to show:

  • How OSIV affects connection pool usage under short and long requests.
  • The performance impact when multiple concurrent requests are executed.
  • The development convenience regarding lazy-loaded relationships.

Setup

git clone https://github.com/ercansormaz/spring-osiv-demo.git
cd spring-osiv-demo
mvn spring-boot:run

Uses H2 in-memory database; no additional setup required.


Configuration

  • spring.jpa.open-in-view defaults to true.
  • HikariCP connection pool configured with maximum pool size = 10.
  • Logging enabled for connection acquire/release:
logging.level.com.zaxxer.hikari=DEBUG

Endpoints

Endpoint Description
/api/short Retrieves data directly from DB
/api/long Retrieves data from DB and simulates a 5-second delay using Thread.sleep

Performance Testing

Use Apache Bench to run load tests:There are two scenarios:

1️⃣ Single Endpoint Run (Concurrency)

  • Concurrency (-c) > 1 is used, but requests are sent to only one endpoint at a time.
  • Example:
ab -n 50 -c 50 -r http://localhost:8080/api/long
ab -n 50 -c 50 -r http://localhost:8080/api/short
  • Purpose: Measure response times of /short or /long in isolation.

2️⃣ Parallel Endpoint Run (Interleaved)

  • Long-running requests are started first (/long).
  • Shortly after, in a separate terminal, concurrent requests are sent to /short.
  • Example:
ab -n 50 -c 50 http://localhost:8080/api/long
# wait a few seconds
ab -n 50 -c 50 http://localhost:8080/api/short
  • Purpose: Demonstrate OSIV impact — long requests occupy DB connections, forcing short requests to wait for a free connection.

Observed Results

Single Endpoint Run (OSIV=true):

Endpoint 50% 95% Max Notes
/long 15s 25s 25s Delay reflected due to Thread.sleep
/short 9ms 11ms 11ms Fast, expected

Parallel Endpoint Run (OSIV=true):

Endpoint 50% 95% Max Notes
/long 15s 25s 25s Connection pool saturated
/short 16ms 25ms 19s Short requests slowed down by long requests 🚨

Parallel Endpoint Run (OSIV=false):

Endpoint 50% 95% Max Notes
/long 5s 5s 5s Connections released immediately
/short 12ms 15ms 15ms Unaffected by long requests ✅

OSIV Implications

Feature OSIV=true OSIV=false
Connection release At request completion At transaction completion
Connection pool usage High for long requests Low (isolated transactions)
Short request latency Can spike significantly under load Stable
PROD suitability ⚠️ Risky ✅ Safe
Development convenience ✅ Easy lazy-loading in controllers ⚠️ Needs explicit fetch

Development Convenience / Lazy Loading

  • With OSIV=true, lazy-loaded relations can be accessed even in any layer.
  • With OSIV=false, accessing lazy relations outside the transactional boundary will throw:
org.hibernate.LazyInitializationException: failed to lazily initialize collection

Recommended approach for OSIV=false:

  • Load all necessary lazy relations inside the service layer using:

    • Fetch join (JOIN FETCH in JPQL)
    • Entity Graphs (@EntityGraph)
    • DTO projection (Spring Data projections)
  • This approach avoids LazyInitializationException while keeping production safe.

🔹 Note: Lazy-loading demonstration will be implemented in a separate branch. The main branch README already describes this scenario, so no separate README is needed in that branch.


Lazy Loading Demonstration (Separate Branch)

This repository also includes a lazy-loading demonstration available in a separate branch (lazy-loading).

That example shows how spring.jpa.open-in-view affects the behavior of @OneToMany and @ManyToOne relationships:

Scenario OSIV Result
Accessing lazy relations in Controller true ✅ Works (but keeps connection open until response)
Accessing lazy relations in Controller false ❌ Throws LazyInitializationException
Using @EntityGraph or fetch join false ✅ Works safely

The branch contains:

  • A DummyParentDummyChild entity pair with a lazy @OneToMany relationship
  • Controller endpoints demonstrating both failing and safe approaches
  • A simple @EntityGraph example as the recommended fix

For details, check the lazy-loading branch in this repository


Summary

  • OSIV=true: Development convenience high, but high risk under production load.
  • OSIV=false: Production safe, requires slightly more coding to handle lazy-loaded entities.
  • Lazy-loading demo will be shown in a dedicated branch using the techniques described above.

📚 Further Reading

You can read a detailed explanation of this project in the blog post here:
👉 Read the Blog Post


🤝 Contributing

Contributions are welcome! Feel free to fork the repo, submit pull requests or open issues.


📜 License

This project is licensed under the MIT License.

About

Spring Boot OSIV demo showing performance impact and lazy-loading practices

Topics

Resources

License

Stars

Watchers

Forks

Languages