Hibernate Tips: Use an auto-incremented column as primary key


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.


Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. If you have a question you like me to answer, please leave a comment below.

Question:

My database supports auto-incremented columns. How can I use them as primary keys in Hibernate?

Solution:

JPA and Hibernate support different strategies to generate primary key values. One of them is the identity strategy which uses an auto-incremented database column.
If you want to use this strategy, you have to annotate the primary key attribute @Id and with the @GeneratedValue annotation and set the strategy attribute to GenerationType.IDENTITY.

The following code snippet shows an example of this annotation

@Entity
public class Author {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", updatable = false, nullable = false)
	private Long id;

	…
}

If you now persist a new Author entity, Hibernate will use the auto-incremented database column to generate the primary key value. You can see that in the log file if you activate the logging for SQL statements.

10:20:08,299 DEBUG [org.hibernate.SQL] - insert into Author (firstName, lastName, version) values (?, ?, ?)
10:20:08,302 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [VARCHAR] - [FirstName]
10:20:08,302 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [2] as [VARCHAR] - [LastName]
10:20:08,303 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [3] as [INTEGER] - [0]
10:20:08,308 DEBUG [org.hibernate.id.IdentifierGeneratorHelper] - Natively generated identity: 1


Databases handle auto-incremented columns very efficiently. But you need to be aware that Hibernate has to perform the INSERT statement immediately to get the primary key value. This prevents it from using different performance optimizations that rely on the delayed execution of database operations.

Further reading:

Auto-incremented database columns are only 1 out of 4 options to generate primary key values. I get into more details about the different strategies in How to generate primary keys with JPA and Hibernate.

Hibernate Tips Book

Get more recipes like this one in my new book Hibernate Tips: More than 70 solutions to common Hibernate problems.

It gives you more than 70 ready-to-use recipes for topics like basic and advanced mappings, logging, Java 8 support, caching, and statically and dynamically defined queries.

Get it now!

One Comment

  1. Avatar photo Sanjeev Dhiman says:

    This is a good tip. I would use “sequence” generator instead due to performance issues you pointed out with “identity”. Now since MySQL doesn’t support “sequences”, I had to use “table” generation strategy.

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator=”test”)
    @TableGenerator(name = “test”, initialValue = 0, allocationSize = 1000, table=”hibernate_sequence_fast_forward”)
    @Column(name = “stg_feedback_fastforward_id”, unique = true, nullable = false)
    public Integer getId() {
    return id;
    }

    create table hibernate_sequence_fast_forward(
    sequence_name VARCHAR(500) NOT NULL,
    next_val bigint(20) NOT NULL
    );

    The only problem that I faced with this is that for every entity I had to create separate tables for hibernate. I somehow couldn’t use just one table for all entities. It might be a problem in my code but I like to know if it is really possible for have just one hibernate table for all your entities. I think it should be since each sequence can be maintained in just one row. yeah?

Comments are closed.