Created
June 3, 2015 08:59
-
-
Save jedvardsson/96af1b86f78762ac12ef to your computer and use it in GitHub Desktop.
How to implement a custom Hibernate enum type indexed on a label
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface LabeledEnum { | |
String getLabel(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class User { | |
@Id | |
private int id; | |
@Type(type = "com.example.hibernate.LabeledEnumType") | |
private Role role; | |
} |
@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.
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
why not use
@javax.persistence.Enumerated(EnumType.STRING) ?