2012-07-16 12 views
10

que tienen una clase de enumeración llamado Estado de la siguiente maneraCómo direccionar los ordinales enteros enumurated personalizado con hibernación

public enum Status { 
    PENDING(0), SUCCESS(1), FAILED(-1); 

    private int st; 

    private Status(int st){ 
     this.st = st; 
    } 
} 

y de otra clase que intenta asignar este status enumeración

public void setStatus(Status status) { 
     this.status = status; 
    } 

    @Enumerated(EnumType.ORDINAL) 
    public Status getStatus() { 
     return status; 
    } 

cuando corro esta código, consigo

java.lang.IllegalArgumentException: Desconocido valor ordinal para la clase de enumeración data.Status: -1 en org.hi bernate.type.EnumType.nullSafeGet (EnumType.java:93) en org.hibernate.type.CustomType.nullSafeGet (CustomType.java:124) en org.hibernate.type.AbstractType.hydrate (AbstractType.java:106) en

pero ya tengo -1 en la definición de enum.

Respuesta

8

Puede definir su propio UserType que defina cómo debe Hibernate asignar esas enumeraciones.

Tenga en cuenta que el ordinal define el índice del valor enum y así FAILED tendría el ordinal 2. Para asignar el enum usando sus propiedades necesita una implementación UserType.

Algunos enlaces:

+2

Utilice el siguiente enlace para un buen tutorial. Me ayudó a entender claramente. http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html –

6

Aquí es una solución en la que se utiliza una etiqueta de cadena en lugar de un int Identificación, sin embargo, es simple de adaptar.

public class User { 
    @Id 
    private int id; 

    @Type(type = "com.example.hibernate.LabeledEnumType") 
    private Role role; 
} 


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 interface LabeledEnum { 
    String getLabel(); 
} 


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(); 
    } 
} 
0

Me gustaría sugerir la siguiente solución. Al principio estaba supprised funcionó pero es muy simple: Para enumeración:

public enum Status { 
    PENDING(0), SUCCESS(1), FAILED(-1); 

    private int status; 

    private Status(int status){ 
     this.status = status; 
    } 

    public String getStatus() { 
     return status; 
    } 

    public static Status parse(int id) { 
     Status status = null; // Default 
     for (Status item : Status.values()) { 
      if (item.getStatus().equals(id)) { 
       Status = item; 
       break; 
      } 
     } 
     return Status; 
    } 
} 

clase

class StatedObject{ 

    @Column("status") 
    private int statusInt; 

    public Status getStatus() { 
     return Status.parse(statusString); 
    } 

    public void setStatus(Status paymentStatus) { 
     this.statusInt = paymentStatus.getStatus(); 
    } 

    public String getStatusInt() { 
     return statusString; 
    } 

    public void setStatusInt(int statusInt) { 
     this.statusInt = statusInt; 
    } 
} 

si está utilizando hibernación en XML de hibernación archivo sería:

<property name="statusInt " column="status" type="java.lang.Integer" /> 

que es

Cuestiones relacionadas