使用固定值映射 JPA 中的枚举? [英] Map enum in JPA with fixed values?

查看:27
本文介绍了使用固定值映射 JPA 中的枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找使用 JPA 映射枚举的不同方法.我特别想设置每个枚举条目的整数值并只保存整数值.

I'm looking for the different ways to map an enum using JPA. I especially want to set the integer value of each enum entry and to save only the integer value.

@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {

  public enum Right {
      READ(100), WRITE(200), EDITOR (300);

      private int value;

      Right(int value) { this.value = value; }

      public int getValue() { return value; }
  };

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "AUTHORITY_ID")
  private Long id;

  // the enum to map : 
  private Right right;
}

一个简单的解决方案是使用带有 EnumType.ORDINAL 的 Enumerated 注解:

A simple solution is to use the Enumerated annotation with EnumType.ORDINAL:

@Column(name = "RIGHT")
@Enumerated(EnumType.ORDINAL)
private Right right;

但在这种情况下,JPA 映射枚举索引 (0,1,2) 而不是我想要的值 (100,200,300).

But in this case JPA maps the enum index (0,1,2) and not the value I want (100,200,300).

我发现的两个解决方案似乎并不简单...

Th two solutions I found do not seem simple...

一个解决方案,此处提出,使用@PrePersist 和@PostLoad将枚举转换为其他字段并将枚举字段标记为瞬态:

A solution, proposed here, uses @PrePersist and @PostLoad to convert the enum to an other field and mark the enum field as transient:

@Basic
private int intValueForAnEnum;

@PrePersist
void populateDBFields() {
  intValueForAnEnum = right.getValue();
}

@PostLoad
void populateTransientFields() {
  right = Right.valueOf(intValueForAnEnum);
}

第二种解决方案

第二种解决方案此处提出 提出了一个通用的转换对象,但看起来仍然很重且面向休眠(@Type 在 Java EE 中似乎不存在):

Second Solution

The second solution proposed here proposed a generic conversion object, but still seems heavy and hibernate-oriented (@Type doesn't seem to exist in Java EE):

@Type(
    type = "org.appfuse.tutorial.commons.hibernate.GenericEnumUserType",
    parameters = {
            @Parameter(
                name  = "enumClass",                      
                value = "Authority$Right"),
            @Parameter(
                name  = "identifierMethod",
                value = "toInt"),
            @Parameter(
                name  = "valueOfMethod",
                value = "fromInt")
            }
)

还有其他解决方案吗?

我有几个想法,但我不知道它们是否存在于 JPA 中:

Is there any other solutions ?

I've several ideas in mind but I don't know if they exist in JPA:

  • 加载和保存Authority对象时,使用Authority类的right成员的setter和getter方法
  • 一个等效的想法是告诉 JPA Right enum 将 enum 转换为 int 和 int 为 enum 的方法是什么
  • 因为我使用的是 Spring,所以有什么方法可以告诉 JPA 使用特定的转换器 (RightEditor) 吗?

推荐答案

对于早于 JPA 2.1 的版本,JPA 仅提供两种处理枚举的方法,通过它们的 name 或通过它们的 序数.并且标准 JPA 不支持自定义类型.所以:

For versions earlier than JPA 2.1, JPA provides only two ways to deal with enums, by their name or by their ordinal. And the standard JPA doesn't support custom types. So:

  • 如果您想进行自定义类型转换,则必须使用提供程序扩展(使用 Hibernate UserType、EclipseLink Converter 等).(第二种解决方案).~或~
  • 您必须使用@PrePersist 和@PostLoad 技巧(第一个解决方案).~或~
  • 注释 getter 和 setter 获取并返回 int 值 ~or~
  • 在实体级别使用整数属性并在 getter 和 setter 中执行转换.
  • If you want to do custom type conversions, you'll have to use a provider extension (with Hibernate UserType, EclipseLink Converter, etc). (the second solution). ~or~
  • You'll have to use the @PrePersist and @PostLoad trick (the first solution). ~or~
  • Annotate getter and setter taking and returning the int value ~or~
  • Use an integer attribute at the entity level and perform a translation in getters and setters.

我将说明最新的选项(这是一个基本实现,根据需要进行调整):

I'll illustrate the latest option (this is a basic implementation, tweak it as required):

@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {

    public enum Right {
        READ(100), WRITE(200), EDITOR (300);

        private int value;

        Right(int value) { this.value = value; }    

        public int getValue() { return value; }

        public static Right parse(int id) {
            Right right = null; // Default
            for (Right item : Right.values()) {
                if (item.getValue()==id) {
                    right = item;
                    break;
                }
            }
            return right;
        }

    };

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "AUTHORITY_ID")
    private Long id;

    @Column(name = "RIGHT_ID")
    private int rightId;

    public Right getRight () {
        return Right.parse(this.rightId);
    }

    public void setRight(Right right) {
        this.rightId = right.getValue();
    }

}

这篇关于使用固定值映射 JPA 中的枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆