Java枚举,JPA和Postgres枚举-如何使它们协同工作?

我们有一个带有postgres枚举的postgres数据库。我们开始在应用程序中构建JPA。我们也有Java枚举,它反映了postgres枚举。现在最大的问题是如何让JPA一方面理解Java枚举,另一方面理解Postgres枚举?Java方面应该很容易,但是我不确定如何进行postgres方面。

回答:

这涉及进行多个映射。

首先,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

}

这不是一个完整的可行解决方案,而只是朝着正确方向的快速指路。

以上是 Java枚举,JPA和Postgres枚举-如何使它们协同工作? 的全部内容, 来源链接: utcz.com/qa/411919.html

回到顶部