java / expert
Snippet
Stateless Result Streaming with JPA and Hibernate
Streaming large datasets requires fine-tuning Hibernate to prevent OutOfMemoryErrors. By setting the fetchSize and enabling readOnly mode, we force the driver to fetch rows in chunks and bypass Hibernate's 1st-level cache overhead.
snippet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Repositorypublic interface LargeDataRepository extends JpaRepository<Entity, Long> {@QueryHints(value = {@QueryHint(name = "org.hibernate.fetchSize", value = "500"),@QueryHint(name = "org.hibernate.readOnly", value = "true"),@QueryHint(name = "org.hibernate.cacheable", value = "false")})@Query("select e from Entity e")Stream<Entity> streamAllByCustomQuery();}// Usage in Service@Transactional(readOnly = true)public void processBatch() {try (Stream<Entity> entityStream = repository.streamAllByCustomQuery()) {entityStream.forEach(e -> { /* process and detach */ });}}
spring
Breakdown
1
Stream<Entity>
Return type that allows processing results one by one without loading the entire list into RAM.
2
org.hibernate.fetchSize
Instructs the JDBC driver to retrieve results in smaller chunks rather than all at once.
3
try (Stream<Entity> ...)
CRITICAL: The stream must be used within a try-with-resources to ensure the underlying database connection closes correctly.