使用枚举作为鉴别器值的SINGLE_TABLE继承策略

2022-08-31 23:52:28

在使用继承策略时,是否可以将枚举用作鉴别器值SINGLE_TABLE?


答案 1

如果您尝试实现的是不要重复鉴别器值,则有一个简单的解决方法。

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FREQUENCY",
    discriminatorType=DiscriminatorType.STRING
)    
public abstract class Event  {
}

@Entity
@DiscriminatorValue(value=Frequency.Values.WEEKLY)
public class WeeklyEvent extends Event {
    …
}

public enum Frequency {
    DAILY(Values.DAILY),
    WEEKLY(Values.WEEKLY),
    MONTHLY(Values.MONTHLY);
    
    private String value;

    …

    public static class Values {
        public static final String DAILY = "D";
        public static final String WEEKLY = "W";
        public static final String MONTHLY = "M";
    }   
}

实际上与Hibernate / JPA无关,但比必须在多个地方维护值更好。


答案 2

我只是想改进关于解决方法@asa的伟大答案。通常,我们经常喜欢使用鉴别器列作为抽象类的属性,并当然使用 a 进行映射。我们仍然可以使用上面提到的解决方案,并强制名称(用于映射列)和值(用作区分器值)之间的一些一致性。这是我的建议:enumenumString

public enum ELanguage {
  JAVA(Values.JAVA), GROOVY(Values.GROOVY);

  private ELanguage (String val) {
     // force equality between name of enum instance, and value of constant
     if (!this.name().equals(val))
        throw new IllegalArgumentException("Incorrect use of ELanguage");
  }

  public static class Values {
     public static final String JAVA= "JAVA";
     public static final String GROOVY= "GROOVY";
  }
}

对于实体,下面是代码:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="LANGUAGE_TYPE", discriminatorType=DiscriminatorType.STRING)    
public abstract class Snippet {
   // update/insert is managed by discriminator mechanics
   @Column(name = "LANGUAGE_TYPE", nullable = false, insertable = false, updatable = false) 
   @Enumerated(EnumType.STRING)
   public ELanguage languageType
}

@Entity
@DiscriminatorValue(value=ELanguage.Values.JAVA)
public class JavaSnippet extends Snippet {
    …
}

仍然不完美,但我认为好一点。