将 Ordinal Enum 值设置为从 1 而不是 0 开始

问题描述 投票:0回答:3

我有一个包含三个值的枚举。它被用作实体 bean 中的属性。

这是 bean 中的属性:

@Enumerated(EnumType.ORDINAL)
private BillingMethod billingMethod;

这是枚举类:

public enum BillingMethod  {
    ONLINEBILL("enum.billingmethod.onlinebill"), // Should be 1, but is now 0 in the database
    PAPERBILL("enum.billingmethod.paperbill"), // Should be 2, but is now 1 in the database
    PRINT("enum.billingmethod.print"); // Should be 3, but is now 2 in the database

    private String tag;

    private BillingMethod(String tag){
        this.tag = tag;
    }

    @Override
    public String getTag() {
        return tag;
    }
}

有一个非常罕见的具体原因,为什么我需要这些值为 1, 2, 3。而不是数据库中通常的 0, 1, 2。

不用担心这里的

tag
,它用于从属性文件中获取字符串表示。

那么,如何将 ORDINAL 设置为从 1 而不是 0 开始呢?

java hibernate jpa enums ordinal
3个回答
5
投票

我看到两个选项:

  1. 最简单:为休眠映射一个整数,在 getter 中对枚举进行解码:

    @Column(...)
    private Integer billingMethod;
    
    public BillingMethod getBillingMethod() {
         // add here better error handling (logging additional info
         // to help diagnose array out of bound exceptions).
         return BillingMethod.values()[billingMethod - 1];
    }
    
    // add a setter doing a similar thing
    

    问题是,如果不进行相同的编码/解码,则使用 hql 或条件搜索将无法工作。不太好。

  2. 创建自定义用户类型。更多信息请参阅参考文档

    然后以这种方式映射该字段:

    @Type("com.fully.qualified.class.name.of.MyUserType")
    private BillingMethod billingMethod;
    

    (当在

    @Type
    注释中使用用户类型的完全限定名称时,不需要注册)

    实现起来有点复杂,但在标准枚举映射可以工作的所有情况下都可以工作


1
投票

我遇到了同样的问题 - 看看这里的解决方案,对我有用:

使用 Hibernate 实现更好的枚举映射

作者使用Hibernate-UserTypes来解决这个问题。我以同样的方式实现了它并且有效!


0
投票

我们可以通过转换器实现它的另一种方法。

实体bean中的属性:

@Convert(converter = BillingMethodIdConverter.class)
private BillingMethod billingMethod;

枚举类:

public enum BillingMethod  {
    ONLINEBILL(1, "enum.billingmethod.onlinebill"),
    PAPERBILL(2, "enum.billingmethod.paperbill"),
    PRINT(3, "enum.billingmethod.print");

    private static final Map<Integer, BillingMethod> mapById =
        Stream.of(BillingMethod.values()).collect(toMap(t -> t.id, identity()));

    public static BillingMethod fromId(Integer id) {
        return Optional.ofNullable(mapById.get(id))
            .orElseThrow(() -> new UnsupportedOperationException());
    }

    private final Integer id;

    private final String tag;

    private BillingMethod(Integer id, String tag) {
        this.id = id;
        this.tag = tag;
    }

    public Integer id() {
        return id;
    }

    public String tag() {
        return tag;
    }
}

转换器:

@Converter
public class BillingMethodIdConverter implements AttributeConverter<BillingMethod, Integer> {
    @Override
    public Integer convertToDatabaseColumn(BillingMethod billingMethod) {
        return billingMethod.id();
    }

    @Override
    public BillingMethod convertToEntityAttribute(Integer id) {
        return BillingMethod.fromId(id);
    }
}

org.hibernate.usertype.UserType
接口的java文档中提到了这种方式。

© www.soinside.com 2019 - 2024. All rights reserved.