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

将JPA中的枚举映射为固定值?

夏法
2023-03-14
问题内容

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

@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一起使用:

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

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

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

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

@Basic
private int intValueForAnEnum;

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

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

第二解决方案
这里提出的第二个解决方案提出了一个通用的转换对象,但它似乎仍然很繁重且面向hibernate(Java EE中似乎不存在@Type):

@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中:

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

问题答案:

对于JPA 2.1之前的版本,JPA仅提供两种方法来按枚举name或按枚举处理枚举ordinal。而且标准的JPA不支持自定义类型。所以:

  • 如果要进行自定义类型转换,则必须使用提供程序扩展(带有Hibernate UserType,EclipseLink Converter等)。(第二个解决方案)。〜或〜
  • 你必须使用@PrePersist@PostLoad技巧(第一个解决方案)。〜或〜
  • 注释gettersetter获取并返回int值〜或〜
  • 在实体级别使用整数属性,并在gettersetter中执行转换。

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

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

}


 类似资料:
  • 我正在使用swagger-codemen-maven-plugin(2.2.1)从YML配置生成java和打字代码类文件。我有两个问题。 如何在YML中定义枚举属性数组? 如何在YML中定义map属性枚举为key,布尔值为value? 让我知道这是可能的还是有任何解决办法?目前,我在java和typescrtipt中定义了enum类,并将其作为字符串传递。谢谢 招摇过市枚举文件 地图物业 更新:

  • 问题内容: 我需要预先将未实现接口的枚举映射到现有数据库,该数据库使用将该枚举存储在与所有者类相同的表中。 在这种情况下应如何处理映射?持久化到数据库不会改变,因为实现该接口的所有枚举都将具有不同的值,但是我不确定应如何从数据库中检索对象(我是否需要自定义映射器,它将尝试实例化一个使用指定的enum类进行枚举吗?Hibernate本身是否支持此功能?)。 问题答案: 可以创建一个自定义(例如thi

  • 问题内容: Hibernate提供的注释支持使用或的两种类型的映射。当我们使用映射时,它使用的“名称” 而不是Enum的表示形式。在数据库列仅包含一个字符的情况下,这是一个问题。例如,我有以下枚举: 当我坚持枚举使用,即hibernate尝试在数据库中存储的值是开放的。但是,我的数据库列仅包含一个字符,因此会引发异常。 克服这个问题的一个办法是改变枚举类型持有单个字符(如,代替,)。但是,这降低了

  • 问题内容: 我需要预先将没有实现接口的枚举映射到现有数据库,该数据库使用将该枚举存储在与所有者类相同的表中。 在这种情况下应如何处理映射?持久化到数据库不会改变,因为实现该接口的所有枚举都将具有不同的值,但是我不确定应如何从数据库中检索对象(我是否需要自定义映射器,它将尝试实例化一个使用指定的enum类进行枚举吗?Hibernate是否本身支持此功能?)。 问题答案: 可以创建一个自定义(例如th

  • 问题内容: Hibernate提供的注释支持使用或两种类型的映射。当我们使用映射时,它使用的“名称” 而不是Enum 的表示形式。在数据库列仅包含一个字符的情况下,这是一个问题。例如,我有以下枚举: 当我坚持枚举使用,即休眠尝试在数据库中存储的值是开放的。但是,我的数据库列仅包含一个字符,因此会引发异常。 克服这个问题的一个办法是改变枚举类型持有单个字符(如,代替,)。但是,这降低了可读性。有什么

  • 我对的枚举有问题。在方法中有两个枚举:和。是内置的Spring枚举,它完美地从String转换为Enum: 但是当我打电话的时候 我阅读并测试了: 带枚举的Spring的@RequestParam Spring Boot能够接受枚举作为请求参数 枚举作为Spring Boot Rest中的请求参数 如何在RequestParm中将多个值转换为枚举? @RequestParam defaultval