fb-pixelWhat is JPA or Java Persistence API and When Is It Used? - Avalith

What is JPA or Java Persistence API and When Is It Used?

AI Site

By Avalith Editorial Team ♦ 1 min read



Almost any application we build, sooner or later, has to deal with the persistence of its data. That is, we need to ensure that the data handled or generated by the application is stored outside of it for later use.

This generally involves the use of a database system, often a traditional SQL-based one.

When developing, modern programs model their information using objects (Object-Oriented Programming), but databases use other paradigms: relationships (sometimes called "Tables") and external keys that relate them. This difference between the way of programming and the way of storing gives rise to what is called "impedance mismatch" and complicates the persistence of objects.

To minimize this mismatch and make it easier for programmers to persist their objects transparently, Object-Relational Mappers (ORMs) are born.

What is JPA?

Now that we are more or less situated, we can start to see what the Java Persistence API or JPA is.

JPA is a specification, specifically JSR 338, that indicates how the persistence (storage) of objects in Java programs should be done.

A specification is simply a document that defines how functionality X should be managed. In this case, a persistence layer with Java objects. For example, it specifies which annotations should be used, how objects should be persisted, how they should be retrieved, what their life cycle is, etc.

How does JPA work?


Since it is a specification, JPA does not provide any class to work with the information. What it does is provide a set of interfaces that we can use to implement the persistence layer of our application, relying on some specific implementation of JPA.

In practice, this means that you will use a persistence library that implements JPA, not JPA directly. For now, it's important to understand the functionalities defined by these interfaces in the specification, as they will be used with each specific implementation.

1.- Entity mapping

The first thing you have to do to use a JPA implementation is to add it to the project and configure the persistence system (for example, the connection string to a database). After that step, the most basic thing you will need to do, which is the core of the specification, is entity mapping.

"Mapping" refers to defining how the classes of your application relate to the elements of your storage system.

If we consider the common case of accessing a relational database, it would be defining:

  • The relationship between the classes of your application and the tables of your database

  • The relationship between the properties of the classes and the fields of the tables

  • The relationship between different classes and the external keys of the database tables

This last point is very important because it allows you to define properties in your classes that are other classes of the application, and automatically retrieve them from persistence based on their relationship.

What JPA defines is also a set of annotations with which we can decorate our classes, properties, and methods to indicate these "mappings."

Additionally, JPA further simplifies the work through the use of default conventions that apply to a high number of common use cases. Therefore, you only need to annotate those behaviors you want to modify or those that cannot be deduced from the classes themselves. For example, although there is an annotation (@Table) to indicate the name of the table in the database associated with a class, by default, if you don't specify anything else, it will be considered that both names match.

2.- Custom data types

All standard fundamental data types are supported by JPA. However, it is also possible to support custom, personalized data types using what are called converters, through the AttributeConverter interface and the @Converter annotation.

3.- JPQL and native queries

JPA also defines its query language called JPQL. It is similar to SQL and is used to launch specific queries based on the entities in the application rather than the tables in the database. In other words, JPQL queries refer to Java classes and their fields instead of tables and columns. They are also independent of the database engine.

JPQL queries are more limited than those offered by the SQL language, especially when considering the peculiarities of each data engine's "dialects," but they are sufficient for a high percentage of cases. In any case, neither type of query should be abused, as they go against the philosophy of ORMs.

JPA Implementations


As mentioned from the beginning, JPA is a specification, so to use it in practice, you need a specific implementation that follows the JPA specification.

The main advantage of this is that if the persistence libraries you use follow the JPA specification, you can switch from one to another, with better performance or better features, without having to touch your code, just by changing the references.

There are various implementations available, such as DataNucleus, ObjectDB, or Apache OpenJPA, but the two most used ones are EclipseLink and, especially, Hibernate.

The reference implementation of JPA, i.e., the implementation provided by the Eclipse Foundation and used to see how to create an ORM based on the specification, is EclipseLink. This implementation includes support for persistence in relational databases, document databases (like MongoDB), XML stores (JAXB specification), and web services databases, making it very comprehensive. It also adds other features on top of JPA, such as events to react to changes in databases or to map entities in different databases at the same time.

Another major JPA implementation is Hibernate, which is currently almost the de facto "standard" since it is the most used, especially in companies. It is so popular that there are even versions for other platforms, such as NHibernate for the .NET platform.

We also have Spring, which includes support for JPA but is not a JPA implementation itself. It needs an implementation like Hibernate or EclipseLink underneath to work.

Spring JPA provides an abstraction over JPA to facilitate the creation of the repository pattern, very useful for creating microservices-based applications. It can generate JPA queries through naming conventions. Additionally, it has another fundamental advantage: it allows declaratively controlling transaction boundaries using the @Transactional annotation.

So, Spring JPA doesn't compete with Hibernate or other implementations; it complements them. You can use Spring JPA with any of them and switch from one to another if needed.

Spring also includes Spring JDBC, which is a data access layer based on the simpler JDBC and useful for making native queries to databases. It has nothing to do with JPA and can be very useful and agile for simple information persistence, avoiding all the fuss of native JDBC.

When you start working with Java, the terminology can be confusing, so this article aims to provide an overview of what JPA is, what it is used for, and how it works. It also emphasizes the importance of its benefits and briefly outlines its main implementations. If you are not sure this approach is the best one for you, contact us and we can cover all your needs right away!