Это включает создание нескольких отображений.
Сначала перечисление Postgres возвращается драйвером JDBC как экземпляр типа PGObject. Свойство type для этого имеет имя вашего перечисления postgres, а свойство value - его значение. (Порядковый номер, однако, не хранится, поэтому технически он больше не является перечислением и, возможно, совершенно бесполезен из-за этого)
В любом случае, если у вас есть такое определение в Postgres:
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
Тогда результирующий набор будет содержать PGObject с типом «mood» и значением «happy» для столбца, имеющего этот тип перечисления, и строку со значением «happy».
Следующее, что нужно сделать, это написать некоторый код перехватчика, который находится между местом, где JPA читает из необработанного результирующего набора, и устанавливает значение для вашей сущности. Например. Предположим, у вас была следующая сущность в Java:
public @Entity class Person {
public static enum Mood {sad, ok, happy}
@Id Long ID;
Mood mood;
}
К сожалению, JPA не предлагает простой точки перехвата, где вы можете выполнить преобразование из PGObject в Java enum Mood. Большинство поставщиков JPA, однако, имеют некоторую частную поддержку для этого. Например, Hibernate имеет для этого аннотации TypeDef и Type (из Hibernate-annotations.jar).
@TypeDef(name="myEnumConverter", typeClass=MyEnumConverter.class)
public @Entity class Person {
public static enum Mood {sad, ok, happy}
@Id Long ID;
@Type(type="myEnumConverter") Mood mood;
Они позволяют вам предоставить экземпляр UserType (из Hibernate-core.jar), который выполняет фактическое преобразование:
public class MyEnumConverter implements UserType {
private static final int[] SQL_TYPES = new int[]{Types.OTHER};
public Object nullSafeGet(ResultSet arg0, String[] arg1, Object arg2) throws HibernateException, SQLException {
Object pgObject = arg0.getObject(X); // X is the column containing the enum
try {
Method valueMethod = pgObject.getClass().getMethod("getValue");
String value = (String)valueMethod.invoke(pgObject);
return Mood.valueOf(value);
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
public int[] sqlTypes() {
return SQL_TYPES;
}
// Rest of methods omitted
}
Это не полное рабочее решение, а просто быстрый указатель в правильном направлении.