Hibernate provides @Enumerated
annotation which supports two types of Enum
mapping either using ORDINAL
or STRING
. When w
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()
The best to customize mapping for enums is to use AttributeConverter
i.e:
@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<Gender, Character> {
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 );
}
}
You can find it in Hibernate docs: http://docs.jboss.org/hibernate/orm/5.0/mappingGuide/en-US/html_single/#d5e678
Check these two articles - http://community.jboss.org/wiki/Java5EnumUserType and http://community.jboss.org/wiki/UserTypeforpersistingaTypesafeEnumerationwithaVARCHARcolumn
They solve the problem by a custom UserType.
Here is an example which uses annotations.
http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html
It's still based off of a custom UserType. Four and a half years later and I'm still not aware of a better way to do this.
Typically, I persist my enum values as a char / int, some simple ID, then use a transient method that finds the appropriate enum by the simple ID value, e.g.
@Transient
public MyEnum getMyEnum() {
return MyEnum.findById(simpleId); //
}
and...
public enum MyEnum {
FOO('F'),
BAR('B');
private char id;
private static Map<Character, MyEnum> myEnumById = new HashMap<Character, MyEnum>();
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;
}
}