The awesome BaseJpaRepository from Hypersistence Utils
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, I’m going to explain how you can use the BaseJpaRepository from the Hypersistence Utils OSS project as an alternative to the default Spring Data JpaRepository
.
The reason why I’m not using the default JpaRepository
on any of my Spring projects is that it provides some terrible defaults that can be very easily misused, like:
So, there are two ways you can fix the problems induced by the default JpaRepository
:
- You can use the
HibernateRepository
to deprecate the questionable methods that you shouldn’t have inherited in every single JPARepository
. - You can use a different
BaseJpaRepository
, as I explained in this article.
While you could create your own BaseJpaRepository
, as I did for this article, it’s much easier to get it from a battle-tested OSS project that you might have already added to your dependency list.
And since Hypersistence Utils already provides the BaseJpaRepository
abstraction and its implementation, this article is going to show you how to use it.
Hypersistence Utils
The Hypersistence Utils project (previously known as Hibernate Types) provides a lot of Spring and Hibernate utilities. For Hibernate, it provides support for non-standard column types (e.g., JSON, ARRAY, Range, Inet, YearMonth), and for Spring, it gives you the BaseJpaRepository
, HibernateRepository
, and a @Retry
annotation to automatically retry a given method that failed.
The Hypersistence Utils dependencies are available via Maven Central, but prior to fetching the dependency, you have to match the right dependency based on the Hibernate version your project is currently using.
For Hibernate 6, you will need to use
<dependency> <groupId>io.hypersistence</groupId> <artifactId>hypersistence-utils-hibernate-60</artifactId> <version>${hypersistence-utils.version}</version> </dependency>
And for Hibernate 5.6 and 5.5, you need to use this dependency:
<dependency> <groupId>io.hypersistence</groupId> <artifactId>hypersistence-utils-hibernate-55</artifactId> <version>${hypersistence-utils.version}</version> </dependency>
There are also dependencies available for Hibernate 5.4, 5.3, 5.2, and 5.1, so check out the GitHub project for more details.
Hypersistence Utils BaseJpaRepository
Once you have added the Hibernate Utils dependency, you can start using the BaseJpaRepository
as the base interface of your Repository
abstractions like this:
@Repository public interface PostRepository extends BaseJpaRepository<Post, Long> { }
The Hypersistence Utils BaseJpaRepository
interface looks like this:
It’s worth noting that you are not limited to the methods defined by the
BaseJpaRepository
interface.For instance, your
Repository
can extend other Spring Data interfaces, like theListPagingAndSortingRepository
:@Repository public interface PostRepository extends BaseJpaRepository<Post, Long>, ListPagingAndSortingRepository<Post, Long> { }
Because the BaseJpaRepository
has an implementation provided by the Hypersistence Utils project, we also need to tell Spring to use that one instead of the default SimpleJpaRepository
.
Therefore, you need to make sure you set the repositoryBaseClass
attribute of the @EnableJpaRepositories
as follows:
@EnableJpaRepositories( value = "your.repository.package", repositoryBaseClass = BaseJpaRepositoryImpl.class )
The your.repository.package
is the Java package of your Spring repositories.
That’s it!
When using the PostRepository
, you’d have to choose the persist
, update
, or merge
method according to your use case instead of the generic save
method that doesn’t always call the right JPA method on your behalf.
@Service @Transactional(readOnly = true) public class ForumServiceImpl implements ForumService { private PostRepository postRepository; public ForumServiceImpl(@Autowired PostRepository postRepository) { this.postRepository = postRepository; } public Post findById(Long id) { return postRepository.findById(id).orElse(null); } @Transactional @Override public Post createPost(Post post) { return postRepository.persist(post); } @Transactional @Override public Post updatePost(Post post) { postRepository.update(post); return post; } }
As simple as that!
If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.
Conclusion
While the Hibernate Types project started as a small collection of non-standard Hibernate Types, with time, it evolved into something much more useful, and that’s how Hypersistence Utils was born.
Not only it provides better Spring Data base repositories, like the BaseJpaRepository utility I’ve just presented, or non-standard Hibernate Types, but the Hypersistence Utils project even provides support for validating the number of SQL statements that are executed by your data access methods.
And this is just the beginning. So, stay tuned for more.
