Hibernate Tips: How to use a custom database sequence


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:

Hibernate uses its default database sequence to generate primary key values. How can I use my own sequence?

Solution:

The JPA specification provides a set of annotations to define the primary key generation strategy.

First of all, you have to annotate the primary key attribute with the @GeneratedValue annotation and set GenerationType.SEQUENCE as the strategy. This tells Hibernate to use a database sequence to generate the primary key value. If you don’t provide any additional information, Hibernate will use its default sequence.

You can configure the name and schema of the database sequence with a @SequenceGenerator annotation like the one you can see in the following code snippet.

@Entity
public class Author {

	@Id
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "author_generator")
	@SequenceGenerator(name="author_generator", sequenceName = "author_seq")
	@Column(name = "id", updatable = false, nullable = false)
	private Long id;
	
	...
	
}

If you now persist a new Author entity, Hibernate will use the configured database sequence “author_seq”. You can see that in the log file, if you activate the logging for SQL statements.

05:20:28,543 DEBUG [org.hibernate.SQL] - select nextval ('author_seq')
05:20:28,570 DEBUG [org.hibernate.SQL] - insert into Author (firstName, lastName, version, id) values (?, ?, ?, ?)
05:20:28,574 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [VARCHAR] - [firstName]
05:20:28,574 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [2] as [VARCHAR] - [lastName]
05:20:28,575 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [3] as [INTEGER] - [0]
05:20:28,576 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [4] as [BIGINT] - [1]

Learn more:

Custom database sequences 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!

4 Comments

  1. Why this code :

    @Entity
    @Table(name = "warehouses")
    undefinedundefined@SequenceGenerator(name = "SEQUENCE_WAREHOUSE", sequenceName = "warehouses_id_seq", initialValue = 1, allocationSize = 1) schema = "public",
    @SequenceGenerator(name = "SEQUENCE_WAREHOUSE", sequenceName = "warehouses_id_seq", schema = "public", allocationSize = 1)
    public class Warehouse implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_WAREHOUSE")
    @Column(name = "id", updatable = false, nullable = false)
    private Integer id;

    doesn't generate any autosync primary key?
    I should get DEFAULT = nextval('warehouses_id_seq'::regclass) for the 'id' column
    but it's not the case.

    Thanks in advance

    1. Avatar photo Thorben Janssen says:

      Hi Philippe,

      Hibernate doesn't use the sequence as a default value. It instead selects the sequence value before it inserts the primary key value. I explain that in more details here: https:undefinedundefinedthorben-janssen.comundefinedjpa-generate-primary-keysundefined

      Regards,
      Thorben

  2. Avatar photo Ashu Bhati says:

    am having problem if a am using generation type- Sequence and giving allocation size and Im size but it take default oracle sequence and giving an error how can solve this …please guide

    1. Avatar photo Thorben Janssen says:

      Sounds like something is wrong with your mapping. Please share the code.

Comments are closed.