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 JPA Repository.
  • 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:

BaseJpaRepository Hypersistence Utils

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 the ListPagingAndSortingRepository:

@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.

Seize the deal! 40% discount. Seize the deal! 40% discount. Seize the deal! 40% discount.

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.

Transactions and Concurrency Control eBook

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.