Skip to content

Instantly share code, notes, and snippets.

@jedvardsson
Created June 3, 2015 08:59
Show Gist options
  • Save jedvardsson/96af1b86f78762ac12ef to your computer and use it in GitHub Desktop.
Save jedvardsson/96af1b86f78762ac12ef to your computer and use it in GitHub Desktop.
How to implement a custom Hibernate enum type indexed on a label
public interface LabeledEnum {
String getLabel();
}
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.DynamicParameterizedType;
import org.hibernate.usertype.UserType;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;
public final class LabeledEnumType implements DynamicParameterizedType, UserType {
private Class<? extends Enum> enumClass;
@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return x == y;
}
@Override
public int hashCode(Object x) throws HibernateException {
return x == null ? 0 : x.hashCode();
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
String label = rs.getString(names[0]);
if (rs.wasNull()) {
return null;
}
for (Enum value : returnedClass().getEnumConstants()) {
if (value instanceof LabeledEnum) {
LabeledEnum labeledEnum = (LabeledEnum) value;
if (labeledEnum.getLabel().equals(label)) {
return value;
}
}
}
throw new IllegalStateException("Unknown " + returnedClass().getSimpleName() + " label");
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.VARCHAR);
} else {
st.setString(index, ((LabeledEnum) value).getLabel());
}
}
@Override
public Object replace(Object original, Object target, Object owner)
throws HibernateException {
return original;
}
@Override
public Class<? extends Enum> returnedClass() {
return enumClass;
}
@Override
public int[] sqlTypes() {
return new int[]{Types.VARCHAR};
}
@Override
public void setParameterValues(Properties parameters) {
ParameterType params = (ParameterType) parameters.get( PARAMETER_TYPE );
enumClass = params.getReturnedClass();
}
}
public enum Role implements LabeledEnum {
ADMIN("admin"), USER("user"), ANONYMOUS("anon");
private final String label;
Role(String label) {
this.label = label;
}
@Override
public String getLabel() {
return label;
}
}
public class User {
@Id
private int id;
@Type(type = "com.example.hibernate.LabeledEnumType")
private Role role;
}
@larvamdp
Copy link

Thanks Jon!
I've been looking for a solution to mapping enums in a fancy way and this one is perfect because is reusable!

@ErwanLeroux
Copy link

why not use
@javax.persistence.Enumerated(EnumType.STRING) ?

public class User {

    @Id
    private int id;

    @javax.persistence.Enumerated(EnumType.STRING)
    private Role role;
}

@jedvardsson
Copy link
Author

@ErwanLeroux it was 5 years ago I created this gist. I’m not using Hibernate or ORM anymore. I guess support for enums is much better now.

@weaselmetal
Copy link

why not use
@javax.persistence.Enumerated(EnumType.STRING) ?

The presented code allows to store some String that's different to the enum's name. Which is still cool, should you want that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment