使用固定值映射 JPA 中的枚举? [英] Map enum in JPA with fixed values?
问题描述
我正在寻找使用 JPA 映射枚举的不同方法.我特别想设置每个枚举条目的整数值并只保存整数值.
I'm looking for the different ways to map an enum using JPA. I especially want to set the integer value of each enum entry and to save only the integer value.
@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 的 Enumerated 注解:
A simple solution is to use the Enumerated annotation with EnumType.ORDINAL:
@Column(name = "RIGHT")
@Enumerated(EnumType.ORDINAL)
private Right right;
但在这种情况下,JPA 映射枚举索引 (0,1,2) 而不是我想要的值 (100,200,300).
But in this case JPA maps the enum index (0,1,2) and not the value I want (100,200,300).
我发现的两个解决方案似乎并不简单...
Th two solutions I found do not seem simple...
一个解决方案,此处提出,使用@PrePersist 和@PostLoad将枚举转换为其他字段并将枚举字段标记为瞬态:
A solution, proposed here, uses @PrePersist and @PostLoad to convert the enum to an other field and mark the enum field as transient:
@Basic
private int intValueForAnEnum;
@PrePersist
void populateDBFields() {
intValueForAnEnum = right.getValue();
}
@PostLoad
void populateTransientFields() {
right = Right.valueOf(intValueForAnEnum);
}
第二种解决方案
第二种解决方案此处提出 提出了一个通用的转换对象,但看起来仍然很重且面向休眠(@Type 在 Java EE 中似乎不存在):
Second Solution
The second solution proposed here proposed a generic conversion object, but still seems heavy and hibernate-oriented (@Type doesn't seem to exist in Java EE):
@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 中:
Is there any other solutions ?
I've several ideas in mind but I don't know if they exist in JPA:
- 加载和保存Authority对象时,使用Authority类的right成员的setter和getter方法
- 一个等效的想法是告诉 JPA Right enum 将 enum 转换为 int 和 int 为 enum 的方法是什么
- 因为我使用的是 Spring,所以有什么方法可以告诉 JPA 使用特定的转换器 (RightEditor) 吗?
推荐答案
对于早于 JPA 2.1 的版本,JPA 仅提供两种处理枚举的方法,通过它们的 name
或通过它们的 序数
.并且标准 JPA 不支持自定义类型.所以:
For versions earlier than JPA 2.1, JPA provides only two ways to deal with enums, by their name
or by their ordinal
. And the standard JPA doesn't support custom types. So:
- 如果您想进行自定义类型转换,则必须使用提供程序扩展(使用 Hibernate
UserType
、EclipseLinkConverter
等).(第二种解决方案).~或~ - 您必须使用@PrePersist 和@PostLoad 技巧(第一个解决方案).~或~
- 注释 getter 和 setter 获取并返回
int
值 ~or~ - 在实体级别使用整数属性并在 getter 和 setter 中执行转换.
- If you want to do custom type conversions, you'll have to use a provider extension (with Hibernate
UserType
, EclipseLinkConverter
, etc). (the second solution). ~or~ - You'll have to use the @PrePersist and @PostLoad trick (the first solution). ~or~
- Annotate getter and setter taking and returning the
int
value ~or~ - Use an integer attribute at the entity level and perform a translation in getters and setters.
我将说明最新的选项(这是一个基本实现,根据需要进行调整):
I'll illustrate the latest option (this is a basic implementation, tweak it as required):
@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();
}
}
这篇关于使用固定值映射 JPA 中的枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!