|

Should you use JPA for your next project?


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, monthly Java Persistence News, monthly coding problems, 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:

  1. 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.
  2. 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:

  1. Standard CRUD (Create, Read, Update, Delete) operations,
  2. 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.

15 Comments

  1. Avatar photo Larry Fredrickson says:

    Excellent overview!

  2. Avatar photo Aurelien Ecoto says:

    Very good points regarding the personal preferences. I have worked with many people who hated JPA/Hibernate without even knowing the @ManyToMany/@ManyToOne annotations.

    One other thing: JPA/Hibernate and native SQL are not mutually exclusive, I’ve been using JDBCTemplate AND Hibernate on multiple projects and it works smoothly.

  3. Avatar photo Torsten Werner says:

    JPA (or more exactly JDBC) cannot be used for non blocking (“reactive”) access to the database.

    1. Avatar photo Thorben Janssen says:

      That’s, of course, correct. The JDBC specification is blocking. So, everything that builds on top of it can’t be reactive.
      As of right now, there are not a lot of reactive database drivers. R2DBC looks promising, but I think it’s still too early to base any long-term decisions on it …

  4. Hi tharben
    I am a fan of hibernate but unfortunately I am beginner
    So I want to learn hibernate could you please guide me
    How can I get knowledge about hibernate

    1. Avatar photo Thorben Janssen says:

      Hi Surendra,

      thanks for the question.
      There are 2 things you can do:

          Or you can go to my free tutorials page and read some of my articles. As a beginner, you should focus on the section “General Concepts”, “Mapping Definitions” and “Most Popular”.

      Regards,
      Thorben

  5. Hi, excellent post!

    As you well said, JPA/Hibernate are very good for most of enterprise projects, mainly the ones that are in a green field.

    Even if your project has lots of complex reports you can continue using JPA/Hibernate with native SQL to take benefits of its data-mapping. If its native query support it’s not enough you can add another framework to solve this issue, like MyBatis or JOOQ. So you don’t need to give up of JPA/Hibernate just because complex queries, just use both!

    Last but not least, another point I think you forgot to talk about has to do with legacy systems and database-based integrations. They have strong influence in your decision! In these cases an ORM like JPA/Hibernate may not be a good choice due to lots of composite keys, lack of normalization, data inconsistency and stored procedures calls. In my opinion you can use another ORM like MyBatis or JOOQ for these use cases.

    What do you think?

    1. Avatar photo Thorben Janssen says:

      Hi Rafael,

      thanks for your comment.

      A combination of Hibernate and a framework like MyBatis or jOOQ can be a good solution as long as both frameworks are used for a good share of the use cases.

      Inconsistent and not normalized databases are always a challenge and ORMs are not the main reason for it (at least in my experience). In the ideal world, you can fix the database model to resolve these issues. If that’s not possible, you have to be very careful when you create your entities and decide which columns you have to map and which you should ignore. It’s hard to give a general recommendation for these issues.

      Stored procedures do not have to be an issue. JPA supports them since 2.1:
      //thorben-janssen.com/call-stored-procedures-jpa/
      //thorben-janssen.com/call-stored-procedures-jpa-part-2/

      Regards,
      Thorben

  6. Great article, thank you!

  7. Seems there are a lot of cases in which JPA is bad choice. What is a good choice for them?

    1. Avatar photo Thorben Janssen says:

      Hi Nataliia,

      yes, there are a lot of use cases in which JPA is not the best choice. But you have to keep in mind, that it is a good choice for the most common use cases. That’s probably the best thing you can achieve with any framework.
      There are lot’s of options for the other use cases like database-specific drivers for NoSQL databases or maybe Hibernate OGM. And jOOQ is an interesting option for complex queries. It’s provides a DSL on top of SQL.

      Regards,
      Thorben

  8. Hi Thorben,

    Really nice post, I completely agree with you that persistence frameworks are chooses based on personal interest and experience.

    I am great fan of hibernate but what other frameworks should we keep in mind if we want to achieve object relational mapping as well as wanted to run complex query on database(RDBM)?

    Regards
    Rahul wagh

    1. Avatar photo Thorben Janssen says:

      Hi Rahul,

      I don’t know of any OR-Mapper that is a good fit for really complex queries. The main issue is that they add an additional layer between the database and your code and that you can’t use the full potential of SQL.
      You would need to combine the OR-Mapper with an additional framework like jOOQ for complex queries.

      Regards,
      Thorben

      1. Avatar photo Thomas Darimont says:

        My approach to complex queries is that I try to keep them out of the application code and rather use use-case specific views in the database that I (or a DBA) can then tune as needed.
        Those views can then be mapped to generic / view specific read-only entities
        which can be queried via simple JPA-QL / native-SQL.
        Filter conditions (e.g. where foo = 42) can then be added as needed and will usually be efficiently propagated to appropriate query parts by the the DBMS via predicate push-down.

        Cheers,
        Thomas

        1. Avatar photo Thorben Janssen says:

          Hi Thomas,

          that’s also a good way to handle complex queries as long as you don’t need to create too many database views.
          Thanks for the tip!

          Regards,
          Thorben

Comments are closed.