Asa*_*Asa 35
如果您要实现的是不重复鉴别器值,则有一个简单的解决方法.
@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";
}
}
Run Code Online (Sandbox Code Playgroud)
不是超级优雅,但比在多个地方保持价值要好.
Gen*_*enu 19
我只想改进@asa关于解决方法的最佳答案.通常,我们经常喜欢使用discriminator列作为抽象类的属性,并使用enum当然映射.我们仍然可以使用上面提到的解决方案并强制enum名称(用于映射列)和String值(用作判别符值)之间的一些一致性.这是我的建议:
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";
}
}
Run Code Online (Sandbox Code Playgroud)
对于实体,这里是代码:
@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 {
…
}
Run Code Online (Sandbox Code Playgroud)
我认为仍然不完美,但更好一点.
不,不幸的是你不能.
如果您尝试使用枚举作为鉴别器值,您将获得类型不匹配异常("无法从MyEnum转换为字符串"),因为唯一允许的鉴别器类型是String,Char和Integer.接下来,我尝试使用enum的名称和序号分别与DiscriminatorType.STRING和DiscriminatorType.INTEGER结合使用.但这也不起作用,因为@DiscriminatorValue注释(与任何其他注释一样)需要一个常量表达式:
这不起作用:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FREQUENCY",
discriminatorType=DiscriminatorType.STRING
)
public abstract class Event {}
@Entity
@DiscriminatorValue(value=Frequency.WEEKLY.name())
public class WeeklyEvent extends Event {
// Exception: The value for annotation attribute DiscriminatorValue.value must be a constant expression
}
Run Code Online (Sandbox Code Playgroud)
也不起作用:
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="FREQUENCY",
discriminatorType=DiscriminatorType.INTEGER
)
public abstract class Event {}
@Entity
@DiscriminatorValue(value=Frequency.WEEKLY.ordinal())
public class WeeklyEvent extends Event {
// Exception: The value for annotation attribute DiscriminatorValue.value must be a constant expression
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我建议反转关系:将鉴别器值定义为实体中的常量,然后将其包装在枚举中:
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name = "FIELD_TYPE",
discriminatorType = DiscriminatorType.STRING
)
public class Shape {}
@Entity
@DiscriminatorValue(Square.DISCRIMINATOR_VALUE)
public class Square extends Shape {
public static final String DISCRIMINATOR_VALUE = "SQUARE";
}
@Entity
@DiscriminatorValue(Circle.DISCRIMINATOR_VALUE)
public class Circle extends Shape {
public static final String DISCRIMINATOR_VALUE = "CIRCLE";
}
@AllArgsConstructor
public enum FieldType {
SHAPE(Shape.DISCRIMINATOR_VALUE),
CIRCLE(Circle.DISCRIMINATOR_VALUE);
@Getter
private final String discriminatorValue;
}
Run Code Online (Sandbox Code Playgroud)
除了消除重复之外,这段代码的耦合度也较低:实体类不依赖于枚举值,无需更改其他代码即可添加;而枚举可以“枚举”来自不同来源的不同类 - 取决于使用它的上下文。