Other Tutorials

Identifiers In Hibernate

Introduction:

Identifiers in Hibernate model the primary key attribute of an entity. It helps us to uniquely identify a JPA entity. Every entity must define an identifier. Also, it can be either simple or composite.

We can define a Hibernate identifier in several ways. In this tutorial, we’ll learn how to do so.

Simple (Single-Valued) Identifier:

If we have a single attribute which can uniquely identify our entity, we can simply annotate that attribute with @Id annotation:

Please remember that the attribute being annotated with @Id should be one of the following types:

  • any Java primitive type or any primitive wrapper type
  • String
  • any of the Java Date types, Or
  • a BigDecimal or a BigInteger

Simple-Generated Identifiers:

What if we want our id values to be auto-generated? For it, we can go a step further and use @GeneratedValue annotation on our identifier field:

When using @GeneratedValue, Hibernate generates the value for our id column while persisting an entity. It’ s important for us to remember that we can only auto-generate either an integral type (int, short or long) or a UUID.

Also, we have four different key generation strategies available to auto-generate our identifier’s value:

1. AUTO Generation Strategy:

Hibernate uses AUTO key generation strategy as its default. The behavior of AUTO strategy slightly varies from one JPA persistence provider to another. In the case of Hibernate, if the identifier attribute is of type UUID it uses the UUIDGenerator or else defaults to the sequence generation strategy.

UUID generation is supported only in Hibernate 5 and higher versions and is of 36 characters in length:

The generated UUID is of the form ‘4ee5a777-7981-4e01-06ab-19aabb2eaa122’.

2. IDENTITY Generation Strategy:

For IDENTITY generation strategy, Hibernate uses IdentityGenerator to generate the identifier values. The values are generated by the identity column of the database and are auto-incremented:

A major drawback of using this strategy is that it doesn’t support batch JDBC insertions.

3. SEQUENCE Generation Strategy:

Here, as the name suggests, database sequences are used to generate the values for our identifier. Hibernate uses SequenceStyleGenerator class internally to achieve it. If our database doesn’t support sequences, it automatically switches to the TABLE key generation strategy.

The SEQUENCE generator generates unique values per sequence. We can either specify the database sequence we wish to use:

Or else Hibernate will use the implicitly-named sequence hibernate_sequence:

to generate the values for our identifier field.

4. TABLE Generation Strategy:

The Hibernate TableGenerator uses a table capable of holding multiple segments of an identifier generation values. Unless specified, Hibernate uses the hibernate_sequences table by default:

We can use @TableGenerator to specify the database table to be used for generating the values:

The TABLE strategy is not very scalable and has a poor performance, so hardly used in real-world implementations. We should always prefer using SEQUENCE generation strategy for all databases that support sequences, which most often all modern databases do.

Composite Identifiers:

Hibernate also allows us to define a composite identifier. To define a composite identifier, we create a primary key class holding the persistent attributes that form our composite key. As per the JPA specifications, our primary key class must be:

  1. Annotated with @EmbeddedId or @IdClass annotations
  2. public and have a public no-args constructor
  3. Serializable
  4. Implementing equals() and hashCode() methods

The attributes making up the composition could be basic, composite or ManyToOne. However, collections and OneToOne attributes aren’t considered appropriate.

1. Using @EmbeddedId:

One way of defining and using a composite key is using @EmbeddedId annotation.

So, let’s start by defining our primary key class and annotating it with @Embeddable:

Now, we can easily reference this class from our entity using @EmbeddedId annotation:

To use our entity class to set or retrieve the primary key attributes, we’ll have something like:

Clearly, our EmployeePurchases entity has a composite key composed of empId and productId.

2. Using @IdClass:

When using @IdClass to create a composite key, we can use @Id annotation to define all our composition attributes in our main class. The code in our primary key class remains as-is but it only acts as a “shadow”:

With this approach, we can directly set the key values using getters/setters of our main entity class:

However, this method doesn’t provide us with a clear separation between the identifier and our entity object.

Derived Identifiers:

In Hibernate, we can choose to copy the entity’s identifier value from one of its associations using @MapsId annotation:

Here, our EmployeeHistory instance will have the exact same id as that of the corresponding Employee instance.

Conclusion:

In this tutorial, we looked at multiple ways to define an identifier in Hibernate. We also covered different key auto-generation strategies.

One comment
Pingback: Identifiers In Hibernate | Howdy Android - Android World

Leave a Comment

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