Streaming the JPA with Spring Boot

Yurko
Level Up Coding
Published in
3 min readJan 9, 2023

--

Photo by benjamin lehman on Unsplash

Accessing databases historically for every Java developer was a headache, but for the last decade (a little bit less), with the release of Spring JPA, it became much easier. And de facto, it became the standard for every modern Java Spring application. Yes, there are alternatives like MyBatis, jOOQ, or others, but the general usage of those is relatively small. The reason for the popularity is quite straightforward — the simplicity of usage, most of the configuration code is hidden from the user.
In this post, I will describe an extension to JPA to give users a choice and one more approach when it comes to working with the DB layer.

Overview

JPAstreamer is a lightweight extension for any JPA provider that allows the creation of Java Streams from database content. So let’s check out what can be done with it and how it can make coding better.

Implementation

Let’s start with a simple setup for gradle (maven is similar but gradle requires fewer characters :)

For the demonstration purpose, I will create three entities to represent the football team with Players and Stadium. For every team there are a bunch of players (one-to-many relation) and one stadium can be used by a few teams (greetings “San Siro”) (many-to-onr relation). Such relations and tables will be sufficient to demonstrate most of the cases.

For the entities, we need to create DTO (Data Transfer Object) to have a middle layer before the database. We need only few — simple TeamDTO, PlayerDTO and DetailedTeamDTO.

Before using JPAStreamer it needs to be initialized with the schema name or injected into the service, in this case Spring will take care of initialisation:

Let’s start with the simple query to get all teams sorted by name and mapped to our simple TeamDTO

Notice Team$ which is a class generated by the JPAstreamer library. The beauty of this approach is that the result returned by our JPA layer is already streamed and we can just apply our filters/mapping to it.

In a similar way, we can filter by some values when doing a query — find all players with a number of matches greater than:

For the final part let’s play around a bit with joining different entities. In order to perform the JOIN operation with JPAstreamer, we just need to specify the joining stream. By default JPAStreamer uses LEFT JOIN(returns all records from the left table, and the matching records from the right table), thus it can be customized in the joining method. In those parts, we can skip mapping the results to DTO to make a point on other parts.

As a start we can simply return all teams with their players mapped to the map:

For the ManyToOne relation, we can search for all players with name and their teams.

Conclusion

After playing around with this library I find it quite useful and am pretty sure I will use it for a number of projects as it makes querying database a little bit cleaner and more “stream” way, which looks better and simpler. I didn’t do any performance analysis, but taking into account that the library transforms the streams into native SQL queries it should not be impactful on a majority of the systems.

Keep coding and have one.

— — — — — — —

Level Up Coding

Thanks for being a part of our community! Before you go:

🚀👉 Join the Level Up talent collective and find an amazing job

--

--

Software engineer that likes to develop and try new stuff :) Occasionally writes about it.