我正在尝试为 Hibernate 实现枚举映射。到目前为止,我已经研究了可用的选项,并且@Enumerated(EnumType.ORDINAL)
和似乎都@Enumerated(EnumType.STRING)
不足以满足我的需求。这@Enumerated(EnumType.ORDINAL)
似乎很容易出错,因为仅仅对枚举常量进行重新排序就会搞乱映射,而且这也@Enumerated(EnumType.STRING)
不够,因为我使用的数据库已经充满了要映射的值,而这些值并不是什么我希望我的枚举常量被命名为(值是外语字符串/整数)。
目前,所有这些值都被映射到字符串/整数属性。同时,属性应该只允许有限的值集(想象一下meetingStatus
属性允许字符串:PLANNED
、CANCELED
和DONE
。或者另一个属性允许有限的整数值集:1
、2
、3
、4
、5
)。
我的想法是用枚举替换实现以提高代码的类型安全性。String / Integer 实现可能导致错误的一个很好的例子是表示此类值的 String 方法参数 - 使用 String 时,任何内容都会发生。另一方面,拥有 Enum 参数类型会引入编译时安全性。
似乎满足我需求的唯一解决方案是为每个枚举实现javax.persistence.AttributeConverter
带有@Converter
注释的自定义。由于我的模型需要相当多的枚举,因此为每个枚举编写自定义转换器很快就开始变得疯狂。因此,我寻找问题的通用解决方案 - >如何为任何类型的枚举编写通用转换器。以下答案在这里有很大帮助: https: //stackoverflow.com/a/23564597/7024402。答案中的代码示例提供了某种通用的实现,但对于每个枚举,仍然需要一个单独的转换器类。答案的作者还继续说道:
“另一种方法是定义一个自定义注释,修补 JPA 提供程序以识别该注释。这样,您可以在构建映射信息时检查字段类型,并将必要的枚举类型提供给纯通用转换器。”
这就是我认为我会感兴趣的。不幸的是,我找不到更多关于此的信息,并且我需要更多的指导来了解需要做什么以及它如何与这种方法一起工作。
public interface PersistableEnum<T> {
T getValue();
}
public enum IntegerEnum implements PersistableEnum<Integer> {
ONE(1),
TWO(2),
THREE(3),
FOUR(4),
FIVE(5),
SIX(6);
private int value;
IntegerEnum(int value) {
this.value = value;
}
@Override
public Integer getValue() {
return value;
}
}
public abstract class PersistableEnumConverter<E extends PersistableEnum<T>, T> implements AttributeConverter<E, T> {
private Class<E> enumType;
public PersistableEnumConverter(Class<E> enumType) {
this.enumType = enumType;
}
@Override
public T convertToDatabaseColumn(E attribute) {
return attribute.getValue();
}
@Override
public E convertToEntityAttribute(T dbData) {
for (E enumConstant : enumType.getEnumConstants()) {
if (enumConstant.getValue().equals(dbData)) {
return enumConstant;
}
}
throw new EnumConversionException(enumType, dbData);
}
}
这就是我能够实现部分通用转换器实现的方式。
目标:无需为每个枚举创建新的转换器类。
Qyouu
墨色风雨
一只萌萌小番薯
相关分类