Enum mapping from custom postgres type with invalid java chars

I work on a legacy project where we have multiple custom postgres enum types. Unfortunately, some of the Postgres enum names have dashes in them like foo-bar that don’t map cleanly to a java enum name. It is illegal to have an enum named foo-bar or foo-baz in Java for example. So I create an enum in Java with a names as follows:

enum MyEnum {
 fooBar("foo-bar"),
 fooBaz("foo-baz);

 private MyEnum(String sqlValue) {
    this.sqlValue = sqlValue;
 }

 public String getSqlValue() {
  return this.sqlValue;
 }

 public static MyEnum fromSqlValue(String sqlValue) {
   MyEnum myEnum = null;
   
   for (MyEnum e : values()) {
     if (e.getSqlValue().equals(sqlValue)) {
       myEnum = e;
       break;
     }
   }

   return myEnum;
 }

 String sqlValue;
}

In an entity, I need to map columns to this enum in both a single value of an enum as well as arrays of these enumerated values. For the arrays I’d like to use Java List of MyEnum but could map to MyEnum if absolutely required.

Is there a way to provide a custom static method to call in a parameter or provide a custom reader that can properly convert the sql values into my enum as in the above class. For example, I’d like to call the static fromSqlValue method above during reading and call the getSqlValue() method during writing.

I’m using hibernate 6.6.1.Final

Any help is greatly apprecated.

Thank you,

Patrick

Support for this was only added in ORM 7.0 through the new annotation @EnumeratedValue from JPA 3.2. You can annotate the sqlValue field in the enum with this new annotation to indicate the value to use.

Since ORM 7.0 is not final yet, you will probably have to implement it in a different way though. One way to do this is to create a subtype of org.hibernate.type.descriptor.java.EnumJavaType for your custom enum and register that via the org.hibernate.annotations.JavaTypeRegistration annotation or at the use site with the org.hibernate.annotations.JavaType annotation.
In that custom subtype, you can override fromName/toName and potentially other methods to make this work for you.

1 Like