Java Enums, JPA and Postgres enums – How do I make them work together?

I’ve actually been using a simpler way than the one with PGObject and Converters. Since in Postgres enums are converted quite naturally to-from text you just need to let it do what it does best. I’ll borrow Arjan’s example of moods, if he doesn’t mind:

The enum type in Postgres:

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');

The class and enum in Java:

public @Entity class Person {

  public static enum Mood {sad, ok, happy};

  @Enumerated(EnumType.STRING)
  Mood mood;

}

That @Enumerated tag says that serialization/deserialization of the enum should be done in text. Without it, it uses int, which is more troublesome than anything.

At this point you have two options. You either:

  1. Add stringtype=unspecified to the connection string, as explained in JDBC connection parameters.This lets Postgres guess the right-side type and convert everything adequately, since it receives something like ‘enum = unknown’, which is an expression it already knows what to do with (feed the ? value to the left-hand type deserialiser). This is the preferred option, as it should work for all simple UDTs such as enums in one go.

    jdbc:postgresql://localhost:5432/dbname?stringtype=unspecified
    

Or:

  1. Create an implicit conversion from varchar to the enum in the database. So in this second case the database receives some assignment or comparison like ‘enum = varchar’ and it finds a rule in its internal catalog saying that it can pass the right-hand value through the serialization function of varchar followed by the deserialization function of the enum. That’s more steps than should be needed; and having too many implicit casts in the catalog can cause arbitrary queries to have ambiguous interpretations, so use it sparingly. The cast creation is:

    CREATE CAST (CHARACTER VARYING as mood) WITH INOUT AS IMPLICIT;

Should work with just that.

Leave a Comment