5 Primary Key Mappings Every Developer Should Know with JPA & Hibernate

Hi, I’m Thorben Janssen from
thoughts-on-java.org. Today I will talk about 5 Primary Key
Mappings you should know while working with JPA and Hibernate. You will learn how to generate unique,
numeric primary key values, use and generate UUIDs as primary keys, map
composite primary keys, share primary keys in one-to-one associations and how
to use Hibernate’s proprietary mapping of natural IDs. But before we dive deeper into today’s
topics, if this is your first time here, and you want to learn how to create your
entity mappings with ease, build incredible efficient persistence layers
with Hibernate and all types of other Java persistence related stuff, start
now by subscribing and clicking the bell, so you don’t miss anything. OK, now that this is done let’s get back
to today’s topic. Mapping a primary key column with JPA
and Hibernate is simple. You just need to add an attribute to
your entity, make sure that its type and name match the database column, annotate
it with @Column and you’re done. You can then use the primary key to load
the entity, and Hibernate sets the primary key value automatically. And if you want to persist a new entity,
you need to set the primary key value programmatically. But with JPA and Hibernate you can do
much more than that. You can: – choose between different
strategies to generate unique primary key values, – use UUIDs and generate
their values, – map composite primary keys, – share primary key values across
associations and – map natural IDs. I will show you how to do all of that in
this video. Let’s start with the generation of
numerical primary key values. Most table models use simple, numerical
primary keys. They are easy to use and very efficient
at the same time. You can either set their values
programmatically or use one of JPA’s generation strategies to create them
automatically. The easiest way to do that is to
annotate your primary key attribute with a @GeneratedValue annotation. Hibernate will then pick a strategy
based on the database-specific dialect. Using the auto strategy, or not
referencing a strategy at all, is the simplest but not the best way. It’s better to specify the strategy. You can choose between: AUTO – to let
Hibernate pick one of the following strategies. SEQUENCE – to use a database sequence. IDENTITY – to use an autoincremented
database columns. TABLE – to use a database table to
simulate a sequence. Specifying the strategy ensures that a
Hibernate update will not accidentally change your generation strategy and if
you’re using the GenerationType.SEQUENCE, it will also
activate some of Hibernate’s performance optimizations. Defining the strategy is simple. You just need to provide it as the value
of the strategy attribute of the @GeneratedValue annotation. This mapping here tells Hibernate to use
a database sequence to generate primary key values. By default, Hibernate uses a sequence
called hibernate_sequence. You can also tell Hibernate to use one
of your own database sequences. I explained that in more details in my
Hibernate Tip: How to use a custom database sequence. UUIDs and numerical primary keys might
seem very different. But with Hibernate, you can map and use
them in almost the same way. The only difference is the type of the
primary key attribute, which is a java.util.UUID instead of a
java.lang.Long. Here is a simple example. The Book entity maps an attribute of
type UUID and uses one of Hibernate’s generators to create primary key values
automatically before persisting a new entity. This is the easiest way to map and
generate a UUID as a primary key. If you want to take a more detailed look
at your mapping options, please watch How to generate UUIDs as primary keys
with Hibernate or you can also find a link to the corresponding article in the
video description. You can then use this Book entity in the
same way as you would use an entity that maps a primary key attribute of type
Long. When Hibernate persists this Book
entity, it first generates a UUID. It then sets that value as the id value
in the SQL INSERT statement. You can see this in the log file if you
activate my recommended development configuration. JPA and Hibernate also provide multiple
ways to map composite primary keys that consist of multiple attributes. Let’s take a look at my preferred
option: the embedded id. I explain this and all other options in
great details in my Advanced Hibernate Online Training The embedded id approach
uses an embeddable to map the primary key attributes. An embeddable is a pure Java class that
is annotated with @Embeddable. It defines attribute mappings in a
reusable way. If you want to use it as an embedded id,
you also need to implement the equals and hashCode methods. You can then use the embeddable class as
the type of your primary key attribute and annotate it with @EmbeddedId. The embeddable and all its attributes
become part of the entity. It follows the same lifecycle, and all
its attributes get mapped to the database table that’s mapped by the
entity. Another common primary key mapping is to
use the same primary key value in a one-to-one association. Here you can see an example: Each
manuscript belongs to one book and each book has one manuscript. That’s a typical one-to-one
association and in most table models, it gets mapped by a shared primary key
value which also acts as the foreign key. You can, of course, map this with JPA
and Hibernate. The only things you need to do are to
model the owning side of the association on the entity that shall reuse the
primary key value and to add a @MapsId annotation to it. When you persist the Manuscript entity,
you only need to set the association to the Book entity. Hibernate will then use the primary key
value of the Book for the new Manuscript. You can dive deeper into this mapping in
Hibernate Tips: How to Share the Primary Key in a One-to-One Association. I will put the link to it to the
description box or you click on the link in the top right corner. Most teams prefer to use a surrogate key
as the primary key. It’s easier to manage in your code,
and all involved systems can handle it more efficiently. But modeling a natural ID is still
useful. You will, most likely, reference them
very often in your use cases. Hibernate provides an annotation to
declare a natural ID and an API to retrieve entities by it. Let’s take a quick look at the most
important details. And if you want to dive deeper, please
read my article @NaturalId – A good way to persist natural IDs with
Hibernate? Which you will find below. You can specify a natural ID by
annotating one or more entity attributes with @NaturalId. I use it in the following code snippet,
to tell Hibernate that the isbn attribute is a natural ID of the Book
entity. After you’ve done that, you can use
the byNaturalId method on Hibernate’s Session interface to create a query that
loads an entity by its natural id. If you’re using JPA’s EntityManager,
you can get the corresponding Session interface by calling the unwrap method. In the next step, you need to provide
the value of the natural id by calling the using method for each attribute
that’s part of the natural id. In this example, the natural id only
consists of the isbn attribute, which I reference using the JPA metamodel class
of the Book entity. And after you provided the natural id
value, you can call the load method to execute the query. When you run this code and activate the
logging of SQL statements, you can see that Hibernate first gets the primary
key value for the provided natural id. It then executes a second query to load
the entity by its primary key. The result of the first query gets
cached so that Hibernate doesn’t need to perform it again. As you can see JPA and Hibernate can do
much more than just mapping a numerical primary key column to an entity
attribute. You can use them to generate unique
primary key values, to map and create UUIDs, to work with composite primary
keys, and to use the same primary key value for associated entities. And Hibernate also supports natural
primary keys with its own, proprietary query mechanism. 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 cheat for
this video, several ebooks about JPA and Hibernate and a video course. 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.

One thought on “5 Primary Key Mappings Every Developer Should Know with JPA & Hibernate

Leave a Reply

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