Hibernate version: 2.1
I tried to search for storage of type-safe enums as var-chars. I found some code, but it seemed like overkill to me. So, I wrote this base class, its quite simple to extend. You can use it to easly store and load enums.
Code:
import net.sf.hibernate.UserType;
import net.sf.hibernate.HibernateException;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
/**
* <code>EnumUserTypeBase</code> is a base class to map enums to varchars in
* hibernate. To use simply extend and create an empty constructor that gives
* the objects in an array to this constructor. To see an example see
* {@link TitleVariantUserType}. Consult the hibernate API documentation for more
* information.
*/
public abstract class EnumUserTypeBase implements UserType {
private static final int[] SQL_TYPES = {Types.VARCHAR};
private final Map _mapping = new HashMap();
private Class _enumClass;
/**
* Call the constructor with all possible enum values. Requires
* atleast one value.
**/
public EnumUserTypeBase(Object[] enums) {
_enumClass = enums[0].getClass();
for (int i=0;i<enums.length;i++) {
_mapping.put(enums[i].toString(), enums[i]);
}
}
/** Returns SQL type (VARCHAR) */
public int[] sqlTypes() {
return SQL_TYPES;
}
/** Return enum class */
public Class returnedClass() {
return _enumClass;
}
/** Since its an immutable enum type, equals is simple */
public boolean equals(Object x, Object y) {
return x == y;
}
/** It has no use making a deep copy of an immutable type */
public Object deepCopy(Object value) { return value; }
/** Its not mutable */
public boolean isMutable() { return false; }
/** Get the enum object */
public Object nullSafeGet(ResultSet resultSet,
String[] names,
Object owner)
throws HibernateException, SQLException {
String name = resultSet.getString(names[0]);
return resultSet.wasNull() ? null : _mapping.get(name);
}
/** Store the object */
public void nullSafeSet(PreparedStatement statement,
Object value,
int index)
throws HibernateException, SQLException {
if (value == null) {
statement.setNull(index, Types.VARCHAR);
} else {
statement.setString(index, value.toString());
}
}
}
For every type-safe enum you need to implement toString correctly. We used it for a TitleVariant typesafe enum. Implementing is a piece of cake:
Code:
public class TitleVariantUserType extends EnumUserTypeBase {
/**
* Gives all possible enumerations through.
*/
public TitleVariantUserType() {
super(new Object[] { TitleVariant.DESCRIPTION, TitleVariant.EXPLANATION,
TitleVariant.LABEL, TitleVariant.TITLE });
}
} // TitleTypeUserType
Thats all. now you can make it like this:
Code:
<property name="variant" type="package.TitleVariantUserType" length="12"/>
I hope this saves a lot of time.
Good luck,
Vincent