2012-07-16 56 views
10

映射我有一個枚舉類命名狀態如下如何定製enumurated整序與Hibernate

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

    private int st; 

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

,並從其他類我試圖映射此狀態枚舉

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

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

當我運行這個代碼,我得到

java.lang.IllegalArgumentException異常:對枚舉類data.Status未知序號值:-1 在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) at

但是我在枚舉定義中已經有了-1。

回答

8

您可以定義自己的UserType,它定義了Hibernate應該如何映射這些枚舉。

請注意,序號定義了枚舉值的索引,因此FAILED將具有序數2.要使用其屬性映射枚舉,需要使用UserType實現。

一些鏈接:

+2

使用下面的鏈接獲得一個很好的教程。這有助於我清楚地理解。 http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html – 2014-06-18 05:08:12

6

這裏是一個字符串標籤使用一個int,而不是一個解決方案身份證,但它很容易適應。

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

我想提出以下解決方法。起初我supprised它的工作,但它是非常簡單的:文件,它會

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

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

如果你是在休眠XML使用Hibernate:

<property name="statusInt " column="status" type="java.lang.Integer" /> 
對於枚舉

這就是它