我正在寻找使用 JPA 映射枚举的不同方法。我特别想设置每个枚举条目的整数值并只保存整数值。
@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; }
一个简单的解决方案是将 Enumerated 注解与 EnumType.ORDINAL 一起使用:
@Column(name = "RIGHT") @Enumerated(EnumType.ORDINAL) private Right right;
但在这种情况下,JPA 映射枚举索引 (0,1,2) 而不是我想要的值 (100,200,300)。
我发现的两个解决方案似乎并不简单......
此处提出的解决方案使用@PrePersist 和@PostLoad 将枚举转换为其他字段并将枚举字段标记为瞬态:
@Basic private int intValueForAnEnum; @PrePersist void populateDBFields() { intValueForAnEnum = right.getValue(); } @PostLoad void populateTransientFields() { right = Right.valueOf(intValueForAnEnum); }
这里提出的第二种解决方案提出了一个通用的转换对象,但看起来仍然很重且面向休眠(@Type 在 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 中:
对于早于 JPA 2.1 的版本,JPA 仅提供两种处理枚举的方法,通过它们的name或它们的ordinal. 并且标准 JPA 不支持自定义类型。所以:
name
ordinal
UserType
Converter
int
我将说明最新的选项(这是一个基本的实现,根据需要进行调整):
@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(); } }