2012-07-16 13 views
10

Ho un classe enum chiamato Stato come segueCome mappare ordinali interi enumurated personalizzato con Hibernate

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

    private int st; 

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

e da altra classe provo a tracciare questo stato enum

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

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

quando corro questo codice, ottengo

java.lang.IllegalArgumentException: Unknown valore ordinale per la classe enum data.Status: -1 a org.hi bernate.type.EnumType.nullSafeGet (EnumType.java:93) presso org.hibernate.type.CustomType.nullSafeGet (CustomType.java:124) presso org.hibernate.type.AbstractType.hydrate (AbstractType.java:106) a

ma ho già -1 nella definizione enum.

risposta

8

È possibile definire il proprio UserType che definisce il modo in cui Hibernate deve mappare tali enumerazioni.

Si noti che l'ordinale definisce l'indice del valore enum e quindi FAILED avrebbe il numero ordinale 2. Per mappare l'enumerazione utilizzando le sue proprietà è necessaria un'implementazione UserType.

Alcuni link:

+2

Utilizzare il collegamento sottostante per un buon tutorial. Mi ha aiutato a capire chiaramente. http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html –

6

Ecco una soluzione in cui l'etichetta stringa viene usato al posto di un int id, tuttavia è semplice da adattare.

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

Vorrei suggerire una soluzione alternativa. All'inizio ero siamo stati sorpresi dall'alta ha funzionato, ma è molto semplice: Per enum:

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; 
    } 
} 

classe

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; 
    } 
} 

se si utilizza Hibernate in ibernazione file XML sarebbe:

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

ovvero

Problemi correlati