|

Hibernate Tips: How to map an Enum to a database column


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:

How can I map an enum attribute to a database column? Which option should I prefer?

Solution:

JPA and Hibernate provide 2 standard options to map an Enum to a database column. You can either use its String representation or its ordinal value.

Both approaches have their drawbacks:
The String representation is verbose, and the renaming of an enum value requires you to also update your database.
The ordinal of an enum value is its position in the enum declaration. This value changes which requires you to update your database when you remove an existing value or don’t add new values to the end of the Enum declaration.

You can define a custom mapping and avoid these issues with an AttributeConverter.

When you use JPA’s and Hibernate’s standard mapping, you can either rely on the default mapping using the ordinal or specify the mapping approach. You can do that with an @Enumerated annotation as I show you in the following examples.

If you don’t provide an @Enumerated annotation or don’t set an EnumType as its value, the ordinal of the enum value gets mapped to the database.

@Entity
public class Author implements Serializable {

	@Enumerated(EnumType.ORDINAL)
	private AuthorStatus status;

	…
}

If you want to map the String representation to the database, you need to annotate the entity attribute with @Enumerated and set EnumType.STRING as its value.

@Entity
public class Author implements Serializable {

	@Enumerated(EnumType.STRING)
	private AuthorStatus status;

	…
}

Learn More:

You can learn more about AttributeConverter and how you can use them to define custom mappings for enums and other Java types in:

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. I have an column that uses EnumType.ORDINAL. I want to change it to
    EnumType.STRING but how do I convert the old data?

    1. Avatar photo Thorben Janssen says:

      Hi Tony,

      you need to do that outside of Hibernate. My recommendation would be to use a Flyway or Liquibase to perform the database migration.
      The migration process needs to consist of 2 steps. You first add the new column and then you execute an SQL UPDATE statement to fill that column based on the previous, ordinal value.

      Regards,
      Thorben

  2. Avatar photo yousafsajjad says:

    This seems really good. How about the case if an enum is removed from the code between different releases? How would it behave? Would it require cleaning up the database?

    1. Avatar photo Thorben Janssen says:

      Yes, you need to make sure that the removed enum value isn’t used in any database record. Otherwise, Hibernate will throw an Exception.
      When you use EnumType.ORDINAL and don’t remove the last value in the enum, the error message might be hard to understand because the ordinal of the other enum values changes. Let’s say your enum has 2 values and you delete the first one. The remaining enum value now has the ordinal 1 (previously it was 2) and Hibernate will throw an Exception when it reads ordinal 2 from the database.

Leave a Reply

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.