Hibernate Tips: How to override the primary key generation strategy

How to override the primary key generation strategy

Get access to all my video courses, 2 monthly Q&A calls, monthly coding challenges, a community of like-minded developers, 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 for a future Hibernate Tip, please leave a comment below.

Question:

You explained that the GenerationType.SEQUENCE is the most efficient primary key generation strategy and that MySQL doesn’t support it.

What shall I do if I need to support PostgreSQL and MySQL with the same application?
Do I need to use the slower GenerationType.IDENTITY with PostgreSQL as well?

Solution:

No, you can use an external mapping file to override the mappings defined via annotations. So, you can use annotations to define your default mapping and override them if necessary.

Define The Default Mapping

In this case, you can use the @GeneratedValue annotation to define the GenerationType.SEQUENCE to generate the primary key values for the Author entity. This is the default strategy for your application. You can use it with all databases that support sequences.

@Entity
public class Author {

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

	...
}

When you now persist a new Author entity, Hibernate retrieves a new primary key value from the database sequence.

20:45:18,203 DEBUG [org.hibernate.SQL] - 
    select
        nextval ('hibernate_sequence')
20:45:18,245 DEBUG [org.hibernate.SQL] - 
    insert 
    into
        Author
        (firstName, lastName, version, id) 
    values
        (?, ?, ?, ?)

Override Parts Of Your Mapping

And when you install your application with a MySQL database, you need to override the generation strategy with an additional mapping file.

By default, JPA and Hibernate check if an orm.xml file exists in the META-INF directory and use it to override the mappings defined by the annotations. So, you just need to provide the mappings you want to change.

In this case, it’s only the generation strategy for the id attribute of the Author entity.

<entity-mappings>
    <entity class="org.thoughts.on.java.model.Author" name="Author">
        <attributes>
            <id name="id">
            	<generated-value strategy="identity"/>
            </id>
        </attributes>
   </entity>
</entity-mappings>

As you can see in the following log message, Hibernate now uses the GenerationType.IDENTITY which uses an auto-incremented database column to generate the primary key value.

20:42:47,414 DEBUG [org.hibernate.SQL] - 
    insert 
    into
        Author
        (firstName, lastName, version) 
    values
        (?, ?, ?)

Learn More

You can read more about the different strategies to generate unique primary key values in:

And if you want to learn more database-specific mapping and query features, you should take a look at:

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!

Related Articles

Responses

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  1. Nice, would that also work for overriding the id generation strategy defined in a mapped super class, for example overriding the id's @GeneratedValue to type IDENTITY:

    public class DefaultRevisionEntity {

    @Id
    @GeneratedValue
    @RevisionNumber
    private int id;

    }

    1. Hi Markus,

      yes, that should also work to override the primary key generation strategy defined on the superclass.

      Regards,
      Thorben