这涉及进行多个映射。
首先,JDBC驱动程序将Postgres枚举作为PGObject类型的实例返回。其type属性具有您的postgres枚举的名称,而value属性则具有其值。(但是序数没有存储,因此从技术上讲它不再是枚举,因此可能完全无用)
无论如何,如果您在Postgres中有这样的定义:
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
然后,结果集将包含类型为“ mood”和值为“ happy”的PGObject,用于具有该枚举类型的列和值为“ happy”的行。
下一步要做的是编写一些拦截器代码,该代码位于JPA从原始结果集中读取并设置实体值的位置之间。例如,假设您在Java中具有以下实体:
public @Entity class Person { public static enum Mood {sad, ok, happy} @Id Long ID; Mood mood;}
不幸的是,JPA没有提供一个简单的拦截点,您可以在其中进行从PGObject到Java枚举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}
这不是一个完整的可行解决方案,而只是朝着正确方向的快速指路。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)