您可以将枚举映射为带有休眠注释的 ORDINAL 或 STRING,例如:
@Enumerated(EnumType.ORDINAL)
private State state;
序数映射将枚举在数据库中的序数位置。如果您更改代码中枚举值的顺序,这将与现有数据库状态冲突。字符串映射将枚举的大写名称放入数据库中。如果你重命名一个枚举值,你会遇到同样的问题。
如果您想定义自定义映射(如您上面的代码),您可以创建org.hibernate.usertype.UserType 的实现,它显式映射枚举。
首先我建议对您的枚举进行一些更改,以使以下操作成为可能:
public enum State {
ACTIVE("active"), INACTIVE("inactive");
private String stateName;
private State(String stateName) {
this.stateName = stateName;
}
public State forStateName(String stateName) {
for(State state : State.values()) {
if (state.stateName().equals(stateName)) {
return state;
}
}
throw new IllegalArgumentException("Unknown state name " + stateName);
}
public String stateName() {
return stateName;
}
}
这是一个简单的 (!) UserType 实现:
public class StateUserType implements UserType {
private static final int[] SQL_TYPES = {Types.VARCHAR};
public int[] sqlTypes() {
return SQL_TYPES;
}
public Class returnedClass() {
return State.class;
}
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner) throws HibernateException, SQLException {
String stateName = resultSet.getString(names[0]);
State result = null;
if (!resultSet.wasNull()) {
result = State.forStateName(stateName);
}
return result;
}
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index) throws HibernateException, SQLException {
if (null == value) {
preparedStatement.setNull(index, Types.VARCHAR);
} else {
preparedStatement.setString(index, ((State)value).stateName());
}
}
public Object deepCopy(Object value) throws HibernateException{
return value;
}
public boolean isMutable() {
return false;
}
public Object assemble(Serializable cached, Object owner) throws HibernateException
return cached;
}
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable)value;
}
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true;
}
if (null == x || null == y) {
return false;
}
return x.equals(y);
}
}
那么映射会变成:
@Type(type="foo.bar.StateUserType")
private State state;
关于如何实现 UserType 的另一个示例,请参见:http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html