The best way to use Spring Data JPA Stream methods
source link: https://vladmihalcea.com/spring-data-jpa-stream/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
The best way to use Spring Data JPA Stream methods
Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Wouldn’t that be just awesome?
Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, or Play Framework.
So, enjoy spending your time on the things you love rather than fixing performance issues in your production system on a Saturday night!
Introduction
In this article, we are going to see what is the best way to use Spring Data JPA Stream query methods.
When having to fetch a larger result set, the advantage of using a Java Stream is that the query result set could be fetched progressively instead of getting all the data at once.
JPA Stream methods
As I explained in this article, since version 2.2, you can now fetch a Stream
using the getResultStream
JPA Query
method.
The getResultStream
will then use the JDBC ResultSet
to stream over the records that are returned by a given query. This approach may be useful when having to process a large volume of data. Therefore, instead of fetching all data at once and putting pressure on the application memory, the result set will be fetched and processed gradually.
Spring Data JPA Stream query methods
If you want to stream over a query result set, then you need to use the Java Stream
return type for your Spring Data JPA query method, as illustrated by the following example:
@Repository public interface PostRepository extends BaseJpaRepository<Post, Long> { @Query ( "" " select p from Post p where date(p.createdOn) >= :sinceDate "" " ) @QueryHints ( @QueryHint (name = AvailableHints.HINT_FETCH_SIZE, value = "25" ) ) Stream<Post> streamByCreatedOnSince( @Param ( "sinceDate" ) LocalDate sinceDate); } |
The FETCH_SIZE
JPA query hint is necessary for PostgreSQL and MySQL to instruct the JDBC Driver to prefetch at most 25 records. Otherwise, the PostgreSQL and MySQL JDBC Drivers would prefetch all the query results prior to traversing the underlying ResultSet
.
For more details about JPA query hints, check out this article.
With the streamByCreatedOnSince
method in place, we can now implement the updatePostCache
service method that will fetch the latest Post
entities and update the in-memory cache.
@Transactional (readOnly = true ) public void updatePostCache() { LocalDate yesterday = LocalDate.now().minusDays( 1 ); try (Stream<Post> postStream = postRepository.streamByCreatedOnSince(yesterday)) { postStream.forEach( post -> executorService.submit(() -> postCache.put(post.getId(), post) ) ); } } |
Notice that the updatePostCache
service method is annotated with @Transactional(readOnly = true)
because we need the database connection to be open throughout the duration of the entire Stream
traversal.
I'm running an online workshop on the 20-21 and 23-24 of November about High-Performance Java Persistence.If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.
Conclusion
Spring Data JPA provides support for Stream query methods, but there are several things to keep in mind prior to using this feature:
- First, you need to make sure you don’t prefetch all the data, as it’s the case with PostgreSQL and MySQL.
- Second, you need to make sure you don’t release the database connection prior to traversing the Stream.
2 Comments on “The best way to use Spring Data JPA Stream methods”
-
Lucian
October 12, 2023@QueryHint(name = AvailableHints.HINT_FETCH_SIZE, value = “25”)
Does this mean that it will fetch query results in batches of 25 records until the entire Stream is traversed?
Leave a Reply Cancel reply
Your email address will not be published. Required fields are marked *
Comment *
Before posting the comment, please take the time to read the FAQ page
Name *
Email *
Website
Notify me of follow-up comments by email.
This site uses Akismet to reduce spam. Learn how your comment data is processed.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK