具有固定值的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: p>
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)而不是值I想要(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将枚举转换为其他字段,并将枚举字段标记为transient:
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);
}
第二个解决方案
第二个解决方案在此提出提出了一个通用的转换对象,但仍然似乎很重,而且以hibernate为导向(@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对象时,使用权限类的正确成员的setter和getter方法
- 一个等同的想法是告诉JPA将枚举转换为int和int到枚举的权限枚举是什么方法
- 因为我是使用Spring,有没有办法告诉JPA使用特定的转换器(RightEditor)?
推荐答案
p>对于早于JPA 2.1的版本,JPA只提供了两种方式来处理枚举,它们的名称
或它们的序号
。而标准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
value〜或〜 - 在实体级别使用整数属性,并在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屋!