我正在寻找使用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; }
一个简单的解决方案是将枚举注释与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); }
第二解决方案 这里提出的第二个解决方案提出了一个通用的转换对象,但它似乎仍然很繁重且面向hibernate(Java EE中似乎不存在@Type):
@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不支持自定义类型。所以:
ordinal
@PrePersist
@PostLoad
getter
setter
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(); } }