springpostgresqlhibernatespring-data-jpahibernate-mapping

Hibernate: How to keep PostgreSQL enum type up-to-date with Java enum?


I'm building a Spring server program which uses a PostgreSQL database. For one of the table columns, I want to restrict the possible values to a static pre-defined set, so I created a PostgreSQL enum type. Then, when beginning to implement the the Spring project, I created a corresponding Java enum and added it to the respective class. With the usual annotations, the conversion between PostgreSQL and Java enum values works perfectly fine.

However, today, I added a value to the Java enum, but to my surprise, spring.jpa.hibernate.ddl-auto=update did not add the new Java enum value to the PostgreSQL enum. Of course, I could just edit the PostgreSQL enum type brand_type manually all the time, but that would be tedious.

How can I ensure that my database's brand_type enum is always up-to-date with the Java enum Brand?

CREATE TYPE brand_type AS ENUM (
    'BOEING',
    'AIRBUS',
    'LOCKHEED',
    'BOMBARDIER'
    -- This PostgreSQL enum shall be updated according to the Java enum “Brand”.
)
@Entity
@Table(name = "planes")
public class Airplane {
    @Column(name = "brand")
    @JdbcType(value = PostgreSQLEnumJdbcType.class) // conversion works fine
    private Brand brand;
}
public enum Brand {
    BOEING,
    AIRBUS,
    LOCKHEED,
    BOMBARDIER
    // When I add DOUGLAS here, the database won't accept this value.
}

On Stack Overflow and elsewhere, all of the questions/answers either focussed on how to map the PostgreSQL enum values to Java enum values or suggested to use the now deprecated @Type and @TypeDef annotations.

Skimming the Hibernate documentation (for the first time), I quickly found the setting hibernate.type.prefer_native_enum_types and thus wrote hibernate.type.prefer_native_enum_types=true to the file hibernate.properties file, but that had no effect.

Since the Hibernate documentation also mentions @JdbcTypeCode(SqlTypes.NAMED_ENUM), I added this annotation to the Airplane#brand field, but that didn't do anything either.


Solution

  • Thanks to the feedback from the comments, I decided to throw away the Java and Postgres enums and use a database table brands mapped to an @Entity class Brand instead.