当前位置: 首页 > 面试题库 >

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

谭泳
2023-03-14
问题内容

我们有一个带有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中,有没有办法从现有枚举中定义一个新枚举?我想要以下功能。 1、2、3和所有这些都必须相同,即, 一个真实的例子是天、星期、周末、讲座、派对等。

  • 我尝试使用@Enumerated annotation映射枚举类型,但得到以下错误: 我的工作:在postgres @entity@table(name=“test_table”)公共类TestTable{... @enumerated(enumtype.string)@column(name=“col”)private TestType col;...}

  • 主要内容:声明枚举,枚举类,为枚举添加方法,EnumMap 与 EnumSet枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。枚举在曰常生活中很常见,例如一个人的性别只能是“男”或者“女”,一周的星期只能是 7 天中的一个等。类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。 在 JDK 1.5 之前没有枚举类型,那时候一般用接口常量来替代。而使用 Java 枚举类型 enum 可以更贴近地表示这种常量。 声明枚举 声明枚举时必须使用 enu

  • 问题内容: 例如,我该怎么做: 结果示例: 问题答案: 迅捷4.2+ 从Swift 4.2(使用Xcode 10)开始,只需添加协议一致性即可从中受益。要添加此协议一致性,您只需要在某处写: 如果枚举是您自己的,则可以直接在声明中指定一致性: 然后,以下代码将打印所有可能的值: 与早期Swift版本(3.x和4.x)的兼容性 如果您需要支持Swift 3.x或4.0,则可以通过添加以下代码来模仿S

  • 问题内容: 这不是卡住我的问题,而是我正在寻找一种编写代码的整洁方法。 本质上,我正在编写一个事件驱动的应用程序。用户触发一个事件,该事件被发送到适当的对象,然后这些对象处理事件。现在,我正在编写偶数处理程序方法,并且希望使用switch语句确定如何处理事件。现在,在我研究通用结构时,事件类非常简单: 然后,在另一堂课中,我会看到类似以下内容的内容: 我会 喜欢 做的就是这样的事情(尽管我当然会坚

  • 问题内容: 我有一个电影租借系统的现有数据库。每部电影都有一个评级属性。在SQL中,他们使用约束来限制此属性的允许值。 我认为使用Java枚举将约束映射到对象世界会很好。但是由于“ PG-13”和“ NC-17”中的特殊字符,不可能简单地获取允许的值。因此,我实现了以下枚举: 使用toString()方法,方向enum-> String可以正常工作,但是String-> enum不能正常工作。我得