Take your skills to the next level!
The Persistence Hub is the place to be for every Java developer. It gives you access to all my premium video courses, 2 monthly Q&A calls, monthly coding challenges, a community of like-minded developers, and regular expert sessions.
Do JPA and Hibernate really fit the project you’re about to start?
This important question gets not asked often enough! And if you don’t think about it in the beginning, it will be difficult to change your mind after the project starts.
Most often, the persistence framework gets selected based on personal preferences. And while these are often based on past experiences, it is not always the best approach.
There are 2 main groups of Java developers out there:
- The ones who don’t like JPA (or Hibernate as its most popular implementation) because they ran into some issues in the past. Due to this, they don’t want to use it at all.
- And then there are the ones who love it and use it in each and every project.
You might expect me to be part of the second group, and that’s not completely wrong. I like Hibernate, but I know that it’s not a good fit for all projects. And as with every tool, it can be really useful or a huge pain, depending on the project or situation in which you want to use it.
So better check your requirements and choose a framework that fits. I prepared a few simple questions to guide you through the decision of choosing JPA or some other persistence framework (please, don’t use plain JDBC).
Which questions should you ask?
What kind of database do you use?
In the past, the answer to this question was simple. Everyone used relational databases, and there was no need to ask this question.
Nowadays, a lot of projects use NoSQL databases, and the question becomes very important!
JPA and Hibernate ORM are designed to work with relational databases. You can, therefore, NOT use them with NoSQL databases.
Most NoSQL databases offer specific database drivers, which are a much better fit. You can also have a look at Hibernate OGM, which applies the JPA API and some of its concepts to NoSQL databases.
Do you use a static or dynamic/configurable domain model?
Configurability has become a popular requirement in recent years, and there are some applications out there that have a configurable domain model and store the data in a relational database. I think that a NoSQL database is, in general, the better solution for these applications, but you can also use a relational database for it. But you should NOT use JPA or Hibernate ORM in these kinds of applications.
The acronym ORM, which stands for Object Relational Mapping, already gives a hint that it might not be a good idea to use it with a configurable domain model. And it becomes perfectly clear if I tell you that the mapping definition is pretty static. Technically, it’s possible to adapt the mapping definition, but it creates so many problems that you should better not try it.
So please, don’t use JPA or Hibernate ORM if your domain model needs to be configurable.
What is the main focus of your use cases?
OK, if you reach this question, you are using a relational database and a static domain model. So we can finally talk about the use cases you have to implement. For this discussion, I like to group them into 2 categories:
- Standard CRUD (Create, Read, Update, Delete) operations,
- Complex reporting and/or data mining related use cases that rely on very complex and advanced queries to retrieve the required data.
If all your use cases fall into the same category, the decision is pretty simple.
JPA and Hibernate ORM are a great fit for standard CRUD operations. They make the implementation of these use cases very easy and efficient. But complex reporting or data mining related use cases are not a good fit because you need to use very complex queries, which you can better implement with SQL than with JPQL or HQL.
Complex reporting or data mining related use cases are not a good fit for JPA and Hibernate. You need to implement very complex queries for these use cases, and you should better implement them with SQL than with JPQL or HQL.
But most applications consist of a lot of different use cases, and not all of them fall into the same category. In that case, JPA and Hibernate ORM might still be a good fit if you don’t have to implement too many complex queries. But more about that in the next question.
How many highly complex queries, stored procedures, and custom database functions will you have?
The last question you have to ask is how complex your queries will be and if you have to use a lot of stored procedures or custom database functions.
You might now wonder what makes a query complex and when it becomes too complex for JPA and Hibernate. If that’s the case, your query is most likely not too complex for Hibernate 😉
As a rule of thumb, queries can be implemented in JPQL as long as you don’t need to extensively use sub-selects, complex functions, recursive SQL or database-specific features.
If you have to implement too many of these, you should have a look at other frameworks. Don’t get me wrong; you can, of course, use native SQL queries with JPA, and JPA 2.1 added real support for stored procedures and database functions. But there are better ways to do that.
You might want to have a look at frameworks like jOOQ or Querydsl if you have to do a lot of these kinds of queries.
But if most of your queries are not too complex, which is the case for a lot of applications, Hibernate and JPA are a great fit. The advantages of the OR-mapping most often outweigh the disadvantages of implementing a few native queries or stored procedure calls with Hibernate.
Summary and why I didn’t talk about performance
OK, it might seem now that JPA and Hibernate are not a good fit for a lot of projects. And that’s not completely wrong. There are a lot of use cases that can be better implemented with other frameworks.
But in my experience, JPA and Hibernate are still a good fit for most applications because they make it very easy to implement CRUD operations. The persistence tier of most applications is not that complex. It uses a relational database with a static domain model and requires a lot of CRUD operations. As soon as you have implemented that part, you can focus on the business tier, which holds the complexity your application has to handle.
And you might wonder why I didn’t ask any questions about performance. The reason for it is that performance requirements are not a problem if your use cases are a good fit for Hibernate and you have good knowledge about the framework. I collected a few performance tips here, and if you want to dive deeper into that topic, have a look at the Persistence Hub.