Lo primero sería definir la enumeración,
public enum Roles implements PersistentEnum { ADMINISTRATOR("Administrator"), USER("User"); private final String role; Roles(String role) { this.role = role; } @Override public String getRole() { return role; } }
Hemos creado dos roles, el administrador para el backend de la página web y los usuarios para el frontend de la misma.
La interfaz PersistentEnum quedaría como sigue,
public interface PersistentEnum { public String getRole(); }
que en el caso de la clase enumeración implementaría el método getRole().
Ahora definimos el Hibernate User Type por medio de una clase abstracta que queda de la siguiente manera,
public abstract class PersistentEnumUserType<T extends PersistentEnum> implements UserType { private Class<T> clazz = null; private static final int[] SQL_TYPES = { Types.VARCHAR }; protected PersistentEnumUserType(Class<T> c) { this.clazz = c; } @Override public int[] sqlTypes() { return SQL_TYPES; } @Override public Class returnedClass() { return clazz; } @Override public Object nullSafeGet(ResultSet resultSet, String[] names, SessionImplementor si, Object owner) throws HibernateException, SQLException { String name = resultSet.getString(names[0]); if (resultSet.wasNull()) return null; for(Object value : returnedClass().getEnumConstants()) { if(name.equals(((PersistentEnum)value).getRole())) { return value; } } throw new IllegalStateException("Unknown " + returnedClass().getSimpleName() + " id"); } @Override public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SessionImplementor si) throws HibernateException, SQLException { if (null == value) { preparedStatement.setNull(index, Types.VARCHAR); } else { preparedStatement.setString(index, ((PersistentEnum)value).getRole()); } } @Override public Object deepCopy(Object value) throws HibernateException { return value; } @Override public boolean isMutable() { return false; } @Override public Object assemble(Serializable cached, Object owner) throws HibernateException { return cached; } @Override public Serializable disassemble(Object value) throws HibernateException { return (Serializable) value; } @Override public Object replace(Object original, Object target, Object owner) throws HibernateException { return original; } public String objectToSQLString(Object value) { return '\'' + ((Enum) value).name() + '\''; } public String toXMLString(Object value) { return ((Enum) value).name(); } @Override public int hashCode(Object x) throws HibernateException { return x.hashCode(); } @Override 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); } }
En este patrón lo principal son los métodos nullSafeGet() y nullSafeSet(). El primero es llamado cuando el resulset de la base de datos es mapeado a un Object, el segundo se llama para mapear los campos de un Object a los parámetros de una sentencia SQL (insert/update/delete). Finalmente el método returnedClass() será sobreescrito en las subclases para llamar a la enumeración,
public class RolesUserType extends PersistentEnumUserType<Roles> { public RolesUserType() { super(Roles.class); } @Override public Class<Roles> returnedClass() { return Roles.class; } }
No hay comentarios:
Publicar un comentario