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

查看:137
本文介绍了具有固定值的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: p>

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)而不是值I想要(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将枚举转换为其他字段,并将枚举字段标记为transient:

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);
}



第二个解决方案



第二个解决方案在此提出提出了一个通用的转换对象,但仍然似乎很重,而且以hibernate为导向(@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对象时,使用权限类的正确成员的setter和getter方法

  • 一个等同的想法是告诉JPA将枚举转换为int和int到枚举的权限枚举是什么方法

  • 因为我是使用Spring,有没有办法告诉JPA使用特定的转换器(RightEditor)?

推荐答案

p>对于早于JPA 2.1的版本,JPA只提供了两种方式来处理枚举,它们的名称或它们的序号。而标准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 value〜或〜

  • 在实体级别使用整数属性,并在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天全站免登陆