【问题标题】:Persist in database enum instance field value instead of enum value坚持数据库枚举实例字段值而不是枚举值
【发布时间】:2017-08-23 10:30:02
【问题描述】:

例如我有这样的枚举

public enum Season {
  WINTER(1), SPRING(10), SUMMER(50), FALL(100);
  private int expectedVisitors;
  private Season(int expectedVisitors) {
    this.expectedVisitors = expectedVisitors;
  }
  public int printExpectedVisitors() {
    return expectedVisitors;
  }
} 

并且季节是一种将存储在数据库中的字段。

@Column(name = "season")`
@Enumerated(EnumType.STRING)
private Season season;

但是我需要存储 int 1/10/100 而不是值 Winter。我应该写什么?有没有可能做这样的事情?

【问题讨论】:

  • 我以前遇到过这种事情。只要记住如果这些值可能发生变化会发生什么。你想要哪些价值观?例如:如果在 2012 年秋季,期望值为 50,您希望该值返回为 50,还是显示值为 100(当前期望值)?这不会是当时的当前期望。您可能希望将枚举作为 setter,但如果您不希望它们更改,请提供一个 int 用于持久性和您的 getter。如果你使用枚举,并且值发生了变化,如果你试图返回一个枚举,你会遇到拉回旧数据的麻烦。

标签: java hibernate enums spring-data


【解决方案1】:

这可以通过使用自定义用户类型来完成,我们经常这样做。

这方面有很多教程,例如这是一个快速谷歌搜索提出的:http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html

您可能想要做不同的事情:您可以在某个包中使用 package-info.java,而不是在每个枚举上使用 @Type(我们正在使用定义用户类型的包)并像这样注释包:

@TypeDefs( {
  @TypeDef( name = "SeasonUserType", typeClass = SeasonUserType.class, defaultForType = Season.class ) 
})
package your.package;

//a few imports here

然后您的实体将只包含以下内容:

@Column(name = "season")
private Season season;

关于枚举的最后一个想法:看起来您想将expectedVisitors 写入数据库,并在读取时使用它将该数字映射回枚举值。虽然这适用于用户类型,但我认为这是一个设计缺陷,因为访问者的数量可能不是一个季节的安全标识符(无论如何它可能会改变,所以它可能根本不应该是硬编码)。

【讨论】:

    【解决方案2】:

    您可以简单地将季节存储为整数:

    @Column(name = "season")
    private Integer season;
    

    并使用 Enums 制作 getter 和 setter:

    public Season getSeason() {
        return Season.byValue(this.season);
    }
    
    public void setSeason(Season season) {
        this.season = season == null ? null : season.getValue();
    }
    

    季节有:

    public Integer getValue() {
        return this.expectedVisitors;
    }
    
    public Season byValue(int value) {
        for (Season s : Season.values()) {
            if (s.getValue() == value) {
                return s;
            }
        }
        return null;
    }
    

    【讨论】:

      【解决方案3】:

      对于纯 JPA 解决方案(无休眠绑定),您必须能够访问 JPA 2.1 及其新的转换器功能,如下所述:

      https://www.thoughts-on-java.org/jpa-21-type-converter-better-way-to/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多