Hibernate 6, Deep Dive: Handling Enums in PostgreSQL

Adeogo Oladipo
3 min readFeb 10, 2024

--

In this article, I’ll do a deep-dive on how enums are handled in Hibernate 6, some possible issues to keep in mind and how to effectively use them.

Like a well-organized library, enums categorize the chaos of possibilities, offering programmers a clear index to navigate the vast volumes of logical choices.

Chat GPT

Enums serve a clear and concise purpose, of summarizing the possible states of an entity. So it makes sense that we use them in our database designs. Hibernate as an ORM has a number of ways to handle enums; some of them good and some with their caveats. In this article, I will try to go through the possibilities and show you how to implement them, what to look out for and the best way to create enums using Hibernate.

For the purposes of our demonstration, we will use a simple `User` entity with a `role` property.

1. The Basic Way

import jakarta.persistence.Entity;
import jakarta.persistence.Enumerated;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "users")
public class User {
@Id
private Long id;
private String name;
private String
private Role role;
}
public enum Role {
TEACHER, STUDENT
}

In this case we just use the enum Role just like we any other data type.

Database POV

create table users
(
id bigint not null
primary key,
email varchar(255),
name varchar(255),
role smallint
constraint users_role_check
check ((role >= 0) AND (role <= 1))
);
  1. A column of type SmallInt is created for the role field. This is because Hibernate uses an integer encoding of the enum data. Meaning, For TEACHER it uses 0and for STUDENT it uses 1 .
  2. A check constraint is created for the role column allowing the possible values of 0 and 1.

Pros

Minimal Code and works great for a basic implementation.

Cons

  1. The raw data in the db is harder to interpret, since you have to always check the enum definition to know what the integer points to.
  2. Adding more enum values at the beginning could cause issues with the assignment since the 0 value is no longer true.

Note: Use this only if you don’t plan to extend the enum and you’re sure you don’t have to extensively debug it.

2. The Enumerated Way

import jakarta.persistence.*;

@Entity
@Table(name = "users-enumerated")
public class User {
@Id
private Long id;
private String name;
private String email;

@Enumerated(EnumType.STRING)
private Role role;
}

For this case we add the @Enumerated(EnumType.STRING) to the field. This tells Hibernate to use the actual enum.name() values instead of the integer values.

Database POV

create table "users-enumerated"
(
id bigint not null
primary key,
email varchar(255),
name varchar(255),
role varchar(255)
constraint "users-enumerated_role_check"
check ((role)::text = ANY ((ARRAY ['TEACHER'::character varying, 'STUDENT'::character varying])::text[]))
);
  1. A column of type varchar(255) is created for the role field.
  2. A check constraint is created for the role column allowing the possible values of 'TEACHER' and 'STUDENT' .

Pros

A bit more Code but works great for most cases.

Cons

Using constraints to enforce the check feels a bit like a hack since it’s not obvious looking at the column in db, that it is an enum.

3. Using Postgres Enum types

In this case, we create the enum type in postgres, using the following command:

CREATE TYPE Role AS ENUM ('TEACHER', 'STUDENT');
import jakarta.persistence.*;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

@Entity
@Table(name = "users-postgres-enum-type")
public class User {
@Id
private Long id;
private String name;
private String email;

@JdbcTypeCode(SqlTypes.NAMED_ENUM)
@Basic(optional = false)
private Role role;
}

Using this method, postgres handles the enum association.

Pros

  1. Much more control over the type since it is created manually.

Cons

  1. Bypasses the ORM, which could lead to tricky issues to debug since you now have two sources of truths as regards to the enum.

Adding a new value to the Enum

Often, you have to modify your enum and add new values. In the next article, I will go through the things to keep in mind when you want to do so.

See you in the next one.

Connect with me on a tech-driven adventure at https://adeogo-oladipo.vercel.app/. Uncover the nuances of my career, from leading cross-functional teams to optimizing system performance. Engage with my Medium articles at Adeogo Oladipo.

--

--

Adeogo Oladipo
Adeogo Oladipo

Written by Adeogo Oladipo

Co-Founder and CTO @DokitariUG. A Strong believer in the Potential in Each Human.

Responses (1)