2012-07-16 12 views
10

Mam klasy enum nazwie status w następujący sposóbJak mapować niestandardowy enumurated porządkowych całkowite z hibernacji

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

    private int st; 

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

a od drugiej klasy próbuję map ten status ENUM

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

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

kiedy uruchomić ten Kod, mam

java.lang.IllegalArgumentException: Nieznany wartość porządkową dla klasy enum data.Status: -1 na org.hi bernate.type.EnumType.nullSafeGet (EnumType.java:93) at org.hibernate.type.CustomType.nullSafeGet (CustomType.java:124) at org.hibernate.type.AbstractType.hydrate (AbstractType.java:106) pod

ale już mam -1 w definicji enum.

Odpowiedz

8

Można zdefiniować własną wartość UserType, która określa, jak hibernacja powinna odwzorować te wyliczenia.

Należy zauważyć, że porządek porządkowy określa indeks wartości wyliczeniowej, a zatem FAILED będzie miał liczbę porządkową 2. Aby odwzorować wyliczenie przy użyciu jego właściwości, należy wykonać implementację UserType.

Niektóre linki:

+2

Skorzystaj z poniższego linku, aby uzyskać dobry samouczek. Pomogło mi to jasno zrozumieć. http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html –

6

Tutaj jest rozwiązanie, w którym etykieta napis jest używany zamiast int id, jednak łatwo go dostosować.

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

Chciałbym zasugerować następujące obejście tego problemu. Na początku byłem supprised to działało, ale to jest naprawdę prosta: Dla 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; 
    } 
} 

klasy

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

jeśli używasz hibernacji w hibernacji pliku XML byłoby:

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

to jest

Powiązane problemy