【问题标题】:How to map JAVA enum to Postgresql Enum using Hibernate/JPA?如何使用 Hibernate/JPA 将 JAVA 枚举映射到 Postgresql 枚举?
【发布时间】:2018-04-11 09:58:09
【问题描述】:

在我的 Hibernate 应用程序中,我想将 Java 枚举映射到 Postgresql 枚举,反之亦然。

我的应用程序正在使用 apache-thrift、hibernate/JPA(用于 ORM 模型)、postgresql DB。

Postgresql DB 已经使用命令定义了枚举

CREATE TYPE status_enum AS ENUM ('UNDER-CONSTRUCTION', 'CLOSED', 'OPEN')

DB 有一些数据,最初很少有元组处于“正在建设”状态。

这是我的解决方案:

枚举映射的自定义类型:

public class PsqlEnum extends EnumType {

    @Override
    public void nullSafeSet(final PreparedStatement st, final Object value, final int index,
            final SharedSessionContractImplementor session) throws SQLException {
        if(value == null) {
            st.setNull( index, Types.OTHER );
        }
        else {
            st.setObject(
                    index,
                    value.toString(),
                    Types.OTHER
            );
        }
    }
}

ORM(休眠)模型的实体:

@Entity
@Table(name = "place")
@TypeDef(
        name = "pgsql_enum",
        typeClass = PsqlEnum.class
)
public class Place implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id",nullable = false)
    @Getter @Setter private Integer id;

    @Column(name = "name")
    @Getter @Setter private String name;


    @Getter
    @Setter
    @Enumerated(EnumType.STRING)
    @Type(type = "pgsql_enum")
    @Column(name = "status_level",columnDefinition = "status_enum")
    private STATUS status;
}

枚举类:

public enum STATUS{
    CLOSED("CLOSED"),
    UNDERCONSTRUCTION("UNDER-CONSTRUCTION"),
    OPEN("OPEN");
    private final String label;
    Exposure(String label){
        this.label = label;
    }
    public String getLabel() {
        return label;
    }

    public static STATUS fromLabel(String label){
        for(STATUS currentEnum:STATUS.values()){
            if(currentEnum.getLabel().equals(label)){
                return currentEnum;
            }
        }
        return null;
    }

    @Override
    public String toString() {
        return this.label;
    }
}

它在插入操作时工作正常,而在检索数据时会引发错误:java.lang.IllegalArgumentException: Unknown name value [UNDER-CONSTRUCTION] for enum class

我在 StackOverflow 中尝试了所有给定的参考解决方案,但没有人能很好地解决我的问题。

【问题讨论】:

  • 如果可能,将 psql 枚举 UNDER-CONSTRUCTION 重命名为 UNDERCONSTRUCTION。所以它匹配你在java中定义的枚举
  • @Lino 这也是其他人使用的实时数据库。所以我无法更改它。

标签: java postgresql hibernate jpa enums


【解决方案1】:

Hibernate 在序列化枚举字段的值时使用Enum 的函数name() 和在反序列化实体时使用Enum.valueOf(...)

这就是为什么你不能在值中使用"UNDER-CONSTRUCTION"

【讨论】:

    【解决方案2】:

    所以我能够弄清楚我错过了什么。基本上我必须在 PsqlEnum.java 文件中同时覆盖 nullSafeGet 和 nullSafeSet。
    我通过关注java file 找到了解决方案。
    所以要么定义自定义 UserType,如在链接中定义,要么自定义 EnumType 都对我有用。
    在自定义 EnumType 中的上述代码 PsqlEnum.java 中,我缺少覆盖 nullSafeGet。

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2019-10-09
      • 2013-01-30
      • 1970-01-01
      • 1970-01-01
      • 2012-04-08
      • 2014-02-21
      • 1970-01-01
      • 2019-08-14
      相关资源
      最近更新 更多