Hibernate @Enumerated映射

Hibernate提供@Enumerated注释,它使用ORDINALSTRING支持两种类型的Enum映射。 当我们使用EnumType.STRING映射时,它采用Enum的“名称”而不是EnumtoString()表示。 在数据库列仅包含一个字符的情况下,这是一个问题。 例如,我有以下枚举:

 public enum Status{ OPEN{ @Override public String toString(){ return "O";} }, WAITLIST{ @Override public String toString(){ return "W";} }, COMPLETE{ @Override public String toString(){ return "C";} } } 

当我使用@Enumerated(EnumType.STRING)持久化枚举Status.OPEN ,Hibernate尝试存储在数据库中的值是OPEN。 但是,我的数据库列只包含一个字符,因此会抛出exception。

解决此问题的一种方法是将Enum类型更改为包含单个字符(如STATUS.OSTATUS.W而不是STATUS.OPENSTATUS.WAITLIST )。 但是,这降低了可读性。 有关保持可读性以及将Enum映射到单个字符列的建议吗?

谢谢。

最好自定义枚举映射是使用AttributeConverter即:

 @Entity public class Person { ... @Basic @Convert( converter=GenderConverter.class ) public Gender gender; } public enum Gender { MALE( 'M' ), FEMALE( 'F' ); private final char code; private Gender(char code) { this.code = code; } public char getCode() { return code; } public static Gender fromCode(char code) { if ( code == 'M' || code == 'm' ) { return MALE; } if ( code == 'F' || code == 'f' ) { return FEMALE; } throw ... } } @Converter public class GenderConverter implements AttributeConverter { public Character convertToDatabaseColumn(Gender value) { if ( value == null ) { return null; } return value.getCode(); } public Gender convertToEntityAttribute(Character value) { if ( value == null ) { return null; } return Gender.fromCode( value ); } } 

你可以在Hibernate docs中找到它: http : //docs.jboss.org/hibernate/orm/5.0/mappingGuide/en-US/html_single/#d5e678

这是一个使用注释的示例。

http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html

它仍然基于自定义UserType。 四年半之后,我仍然没有意识到更好的方法。

通常,我将我的枚举值保存为char / int,一些简单的ID,然后使用一个瞬态方法,通过简单的ID值找到适当的枚举,例如

 @Transient public MyEnum getMyEnum() { return MyEnum.findById(simpleId); // } 

和…

 public enum MyEnum { FOO('F'), BAR('B'); private char id; private static Map myEnumById = new HashMap(); static { for (MyEnum myEnum : values()) { myEnumById.put(myEnum.getId(), myEnum); } } private MyEnum(char id) { this.id = id; } public static MyEnum findById(char id) { return myEnumById.get(id); } public char getId() { return id; } } 
 public enum Status { OPEN("O"), WAITLIST("W"), COMPLETE("C") private String description; private Status(String description) { this.description = description; } public String getDescription() { return description; } } and then when you read it: Status.OPEN.getDescription()