Hi, I’m Thorben Janssen from thoughts-on-java.org and today, I will talk about the differences between JPA, Hibernate and EclipseLink. When people are new to JPA, Hibernate or EclipseLink, they are often confused about the difference between them and which one they should use in their project. If you’re one of them, don’t worry. It’s a lot easier than it seems. But before we start, if you are finding me for the first time, please subscribe to this channel. I’m publishing new videos about JPA and Hibernate twice a week. Let’s take a look at the JPA specification first. JPA is an abbreviation that stands for Java Persistence API. It’s a specification which is part of Java EE and defines an API for object-relational mappings and for managing persistent objects. You can use this API in Java SE and Java EE environments. The specification is currently available in version 2.2. You can download the document at the link here on the slide I will also add it to the video description below. The API jar is available at the following Maven coordinates. JPA itself doesn’t provide any implementation classes. the api jar just contains a set of interfaces which you can use to implement your persistence layer. But you can’t use JPA on its own. You need a JPA provider which implements the specification. There are several options available. The most popular ones are Hibernate and EclipseLink. But more about that later. Until recently, JPA was managed and developed by an expert group following the Java Community Process That changed when Oracle announced to transfer all Java EE specifications to the Eclipse Foundation. We’re now in the middle of the transition process, and a new specification process will be defined soon. The specification defines most of the features that I explained on my blog and in the videos on this channel. You can use them with all compliant JPA implementations. Let’s take a look at some of the most important
ones. Before you can start using JPA, you need to add it to your project, configure a persistence unit, map entities to your database tables and bootstrap it. You probably already know how to do that, and I explained it in great
detail in my Getting Started with Hibernate article. You will find a link to it below. So, let’s skip this part here and talk about the more interesting features. JPA doesn’t only enable you to map simple
entity attributes to database columns, but it also allows you to map associations between
database tables to entity attributes. Here you can see an example of a many-to-one association mapping. These mappings make your entity model very comfortable to use because you just need to call a getter method on an entity to load the associated entities. In the background, the persistence provider performs all the required database operations to retrieve and manage the association. As comfortable to use as this might be, this feature often causes performance problems. Before you start to model associations between your entities, please make sure you understand the effect of JPA’s FetchTypes to avoid n+1 select issues. JPA also defines its own query language, called JPQL. It’s similar to SQL but enables you to define queries based on the mapped domain model instead of the database’s table model. Here you can see a simple JPQL query. You can define an ad-hoc query by calling the createQuery method on the EntityManager. As you can see, the syntax looks very similar to SQL. If you’re not familiar with JPQL, please take a look at my JPQL Guide in which I explain its syntax and capabilities in great detail. I will add link to it, to the description. When you execute such a query, your persistence provider interprets the JPQL statement and generates an SQL query for it. By doing that, the persistence provider adapts the query to the database-specific SQL dialect and improves the portability of your application. Unfortunately, that also limits you to the query features defined by the specification or proprietarily supported by your persistence provider. This feature set is significantly smaller than the one offered by SQL and doesn’t include any proprietary database features. But that doesn’t mean that you can’t use any advanced or complex queries with JPA. It’s designed as a leaky abstraction and allows you to execute native SQL queries. These are not parsed by your persistence provider, and you can use all features supported by your database. But please be aware that this might negatively affect your database portability. Executing a native query is pretty simple. You just need to call the createNativeQuery method instead of the createQuery method on your EntityManager with a native SQL query. The JPA specification defines the mapping for most standard types without limiting you to them. Since JPA 2.1, you can easily support custom data types with an AttributeConverter. You just need to implement the AttributeConverter interface and annotate the class with a Converterannotation. Here’s an example of an attribute converter
that defines a custom mapping for my AuthorStatus enum. The convertToDatabaseColumn method converts the enum to a String which will be stored in the database. And the convertToEntityAttribute implements the inverse operation and maps the String to an enum value. As I said before, you need a persistence provider, if you want to use the JPA specification in your project. It implements the interfaces as defined by the specification. The most popular ones are EclipseLink and Hibernate. One advantage of the standardized API provided by JPA is that you just need to add its implementation at runtime and that you can replace it with a different one without changing any code. The standardized API makes EclipseLink and
Hibernate interchangeable. So, why do you need different implementations? The JPA implementations are managed by independent teams, and you can choose the one that provides the best performance or support for your application and technology stack. They also differentiate themselves by providing additional, non-standard functionalities. This is often used to drive innovation. Today’s popular, proprietary feature might be the first step to the next addition to the JPA standard. Using any of these proprietary features, obviously, makes it a lot harder to replace a specific JPA
implementation. So, use it with care EclipseLink is JPA’s reference implementation and implements JPA version 2.2. It was one of the first projects that became part of EE4J. In addition to the features defined by the JPA standard, EclipseLink also offers several interesting, proprietary features, like: Handling of database change events Composite persistence units to map entities to tables in multiple databases Or Support for multi-tenancy I’ll provide links to all of these features in the video description. The easiest way to add EclipseLink to your project is to use the following Maven coordinates. Hibernate is Red Hat’s very popular implementation of the JPA specification and it also implements JPA version 2.2. Similar to EclipseLink, Hibernate provides a bunch of interesting, proprietary features, like: Management of creation and update timestamps Extended support for natural IDs Loading multiple entities by their primary key Or joining unassociated entities in queries and it also supports for multi-tenancy The following Maven dependency adds Hibernate
to your project. OK, that’s it for today. If you want to learn more about Hibernate, you should join the free Thoughts on Java Library. It gives you free access to a lot of member-only content like a cheat for this video and an ebook about using native queries
with JPA and Hibernate. I’ll add the link to it to the video description below. And if you like today’s video, please give it a thumbs up and subscribe below. Bye