2012-07-16 16 views
10

के साथ कस्टम enumurated पूर्णांक ऑर्डिनल्स मैप करने के लिए मैं कैसे के रूप मेंहाइबरनेट

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

    private int st; 

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

इस प्रकार एक enum वर्ग नामित स्थिति है और अन्य वर्ग से मैं इस स्थिति enum

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

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

जब मैं इस चलाने मैप करने के लिए कोशिश कोड, मैं

java.lang.IllegalArgumentException: enum वर्ग data.Status के लिए अज्ञात क्रमसूचक मूल्य: -1 org.hi पर bernate.type.EnumType.nullSafeGet (EnumType.java:93) org.hibernate.type.CustomType.nullSafeGet (CustomType.java:124) पर org.hibernate.type.AbstractType.hydrate पर (AbstractType.java:106)

लेकिन मेरे पास पहले से ही enum परिभाषा है।

उत्तर

8

आप अपना खुद का UserType परिभाषित कर सकते हैं जो परिभाषित करता है कि कैसे हाइबरनेट को उन enums को मानचित्र करना चाहिए।

ध्यान दें कि ordinal enum value की अनुक्रमणिका को परिभाषित करता है और इस प्रकार FAILED में सामान्य होता है 2. इसके गुणों का उपयोग करके enum को मैप करने के लिए आपको UserType कार्यान्वयन की आवश्यकता होती है।

कुछ लिंक:

+2

एक अच्छे ट्यूटोरियल के लिए नीचे दिए गए लिंक का उपयोग करें। इससे मुझे स्पष्ट रूप से समझने में मदद मिली। http://www.gabiaxel.com/2011/01/better-enum-mapping-with-hibernate.html –

6

यहाँ एक समाधान जहां एक स्ट्रिंग लेबल किसी पूर्णांक के बजाय प्रयोग किया जाता है आईडी, हालांकि यह अनुकूलित करने के लिए आसान है।

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 था यह काम किया लेकिन यह वास्तव में सरल है: 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; 
    } 
} 

वर्ग

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

अगर आप हाइबरनेट एक्सएमएल में हाइबरनेट उपयोग कर रहे हैं फ़ाइल यह होगा:

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

यह