2011-09-29 17 views
6

पर पोस्टग्रेस एनम को मैप करने का प्रयास कर रहा हूं, मैं एक पोस्टग्रेर्स कस्टम प्रकार, ट्रांसमिशन_रेसल्ट नामक एक हाइबरनेट/जेपीए POJO को मैप करने की कोशिश कर रहा हूं। Postgres कस्टम प्रकार स्ट्रिंग मानों के enum प्रकार कम या कम है।हाइबरनेट/जेपीए pojo

मैंने एक कस्टम EnumUserType बनाया है जिसे PGEnumUserType कहा जाता है साथ ही साथ पोस्टमर्स गणना मूल्यों का प्रतिनिधित्व करने वाला एक एनम क्लास भी बनाया गया है। जब मैं इसे एक वास्तविक डेटाबेस के विरुद्ध चलाता हूं, तो मुझे निम्न त्रुटि मिलती है: 'त्रुटि: कॉलम "स्थिति" ट्रांसमिशन_रेसल्ट प्रकार का है लेकिन अभिव्यक्ति प्रकार के चरित्र संकेत है: आपको अभिव्यक्ति को फिर से लिखना या डालना होगा। स्थिति: 135 '

इसे देखने पर, मुझे लगा कि मुझे अपने एसक्लटाइप को प्रकारों में बदलने की ज़रूरत है। अन्यथा। लेकिन संदेश के साथ ऐसा करने के लिए मेरे एकीकरण परीक्षण (मेमोरी डीबी में हाइपरएसक्यूएल का उपयोग करके) को तोड़ता है: 'के कारण: java.sql.SQLException: तालिका में तालिका नहीं मिली [नामांकन 0 _। "आईडी" id1_47_0_ के रूप में, नामांकन 0 _। "Tpa_approval_id" tpa2_47_0_, नामांकन 0 _। "tpa_status_code" tpa3_47_0_, नामांकन 0 _। "status_message" को स्थिति 4_47_0_, नामांकन 0 _। "स्वीकृति_आईडी" स्वीकृति 5_47_0_, नामांकन 0 _। "ट्रांसमिशन_डेट" ट्रांसमिस 6_47_0_, नामांकन 0 _। "स्थिति" स्थिति 7_47_0_, नामांकन 0 _। "ट्रांसमीटर" ट्रांसमिट 8_47_0_ के रूप में "प्रसारण" नामांकन 0_ जहां नामांकन 0 _। "आईडी" =?] '

मुझे यकीन नहीं है कि इस त्रुटि में sqlType परिणामों को क्यों बदल रहा है। किसी भी मदद की सराहना की है।

जेपीए/हाइबरनेट निकाय:

@Entity 
@Access(javax.persistence.AccessType.PROPERTY) 
@Table(name="transmissions") 
public class EnrollmentCycleTransmission { 

// elements of enum status column 
private static final String ACCEPTED_TRANSMISSION = "accepted"; 
private static final String REJECTED_TRANSMISSION = "rejected"; 
private static final String DUPLICATE_TRANSMISSION = "duplicate"; 
private static final String EXCEPTION_TRANSMISSION = "exception"; 
private static final String RETRY_TRANSMISSION = "retry"; 

private Long transmissionID; 
private Long approvalID; 
private Long transmitterID; 
private TransmissionStatusType transmissionStatus; 
private Date transmissionDate; 
private String TPAApprovalID; 
private String TPAStatusCode; 
private String TPAStatusMessage; 


@Column(name = "id") 
@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
public Long getTransmissionID() { 
    return transmissionID; 
} 

public void setTransmissionID(Long transmissionID) { 
    this.transmissionID = transmissionID; 
} 

@Column(name = "approval_id") 
public Long getApprovalID() { 
    return approvalID; 
} 

public void setApprovalID(Long approvalID) { 
    this.approvalID = approvalID; 
} 

@Column(name = "transmitter") 
public Long getTransmitterID() { 
    return transmitterID; 
} 

public void setTransmitterID(Long transmitterID) { 
    this.transmitterID = transmitterID; 
} 

@Column(name = "status") 
@Type(type = "org.fuwt.model.PGEnumUserType" , parameters ={@org.hibernate.annotations.Parameter(name = "enumClassName",value = "org.fuwt.model.enrollment.TransmissionStatusType")}) 
public TransmissionStatusType getTransmissionStatus() { 
    return this.transmissionStatus ; 
} 

public void setTransmissionStatus(TransmissionStatusType transmissionStatus) { 
    this.transmissionStatus = transmissionStatus; 
} 

@Column(name = "transmission_date") 
public Date getTransmissionDate() { 
    return transmissionDate; 
} 

public void setTransmissionDate(Date transmissionDate) { 
    this.transmissionDate = transmissionDate; 
} 

@Column(name = "tpa_approval_id") 
public String getTPAApprovalID() { 
    return TPAApprovalID; 
} 

public void setTPAApprovalID(String TPAApprovalID) { 
    this.TPAApprovalID = TPAApprovalID; 
} 

@Column(name = "tpa_status_code") 
public String getTPAStatusCode() { 
    return TPAStatusCode; 
} 

public void setTPAStatusCode(String TPAStatusCode) { 
    this.TPAStatusCode = TPAStatusCode; 
} 

@Column(name = "status_message") 
public String getTPAStatusMessage() { 
    return TPAStatusMessage; 
} 

public void setTPAStatusMessage(String TPAStatusMessage) { 
    this.TPAStatusMessage = TPAStatusMessage; 
} 
} 

कस्टम EnumUserType:

public class PGEnumUserType implements UserType, ParameterizedType { 

private Class<Enum> enumClass; 

public PGEnumUserType(){ 
    super(); 
} 

public void setParameterValues(Properties parameters) { 
    String enumClassName = parameters.getProperty("enumClassName"); 
    try { 
     enumClass = (Class<Enum>) Class.forName(enumClassName); 
    } catch (ClassNotFoundException e) { 
     throw new HibernateException("Enum class not found ", e); 
    } 

} 

public int[] sqlTypes() { 
    return new int[] {Types.VARCHAR}; 
} 

public Class returnedClass() { 
    return enumClass; 
} 

public boolean equals(Object x, Object y) throws HibernateException { 
    return x==y; 
} 

public int hashCode(Object x) throws HibernateException { 
    return x.hashCode(); 
} 

public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { 
    String name = rs.getString(names[0]); 
    return rs.wasNull() ? null: Enum.valueOf(enumClass,name); 
} 

public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { 
    if (value == null) { 
     st.setNull(index, Types.VARCHAR); 
    } 
    else { 
     st.setString(index,((Enum) value).name()); 
    } 
} 

public Object deepCopy(Object value) throws HibernateException { 
    return value; 
} 

public boolean isMutable() { 
    return false; //To change body of implemented methods use File | Settings | File Templates. 
} 

public Serializable disassemble(Object value) throws HibernateException { 
    return (Enum) value; 
} 

public Object assemble(Serializable cached, Object owner) throws HibernateException { 
    return cached; 
} 

public Object replace(Object original, Object target, Object owner) throws HibernateException { 
    return original; 
} 

public Object fromXMLString(String xmlValue) { 
    return Enum.valueOf(enumClass, xmlValue); 
} 

public String objectToSQLString(Object value) { 
    return '\'' + ((Enum) value).name() + '\''; 
} 

public String toXMLString(Object value) { 
    return ((Enum) value).name(); 
} 
} 

Enum वर्ग:

public enum TransmissionStatusType { 
accepted, 
rejected, 
duplicate, 
exception, 
retry} 

उत्तर

9

मैं यह पता लगा। मुझे nullSafeSet फ़ंक्शन में setString के बजाय setObject का उपयोग करने की आवश्यकता है और java.sql.type के रूप में javabq को यह बताएं कि यह एक पोस्टग्रेस प्रकार था।

public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException { 
    if (value == null) { 
     st.setNull(index, Types.VARCHAR); 
    } 
    else { 
//   previously used setString, but this causes postgresql to bark about incompatible types. 
//   now using setObject passing in the java type for the postgres enum object 
//   st.setString(index,((Enum) value).name()); 
     st.setObject(index,((Enum) value), Types.OTHER); 
    } 
} 
0

जैसा कि मैंने explained in this article, यह मानते हुए आप PostgreSQL में post_status_info enum प्रकार निम्नलिखित हैं:

:

CREATE TYPE post_status_info AS ENUM (
    'PENDING', 
    'APPROVED', 
    'SPAM' 
) 

आप आसानी से कस्टम निम्नलिखित हाइबरनेट प्रकार का उपयोग कर एक PostgreSQL Enum स्तंभ प्रकार के लिए जावा Enum मैप कर सकते हैं

public class PostgreSQLEnumType extends org.hibernate.type.EnumType { 

    public void nullSafeSet(
      PreparedStatement st, 
      Object value, 
      int index, 
      SharedSessionContractImplementor session) 
     throws HibernateException, SQLException { 
     if(value == null) { 
      st.setNull(index, Types.OTHER); 
     } 
     else { 
      st.setObject( 
       index, 
       value.toString(), 
       Types.OTHER 
      ); 
     } 
    } 
} 

इसका उपयोग करने के लिए, आपको निम्न उदाहरण में सचित्र के रूप में हाइबरनेट @Type एनोटेशन के साथ फ़ील्ड को एनोटेट करने की आवश्यकता है:

@Entity(name = "Post") 
@Table(name = "post") 
@TypeDef(
    name = "pgsql_enum", 
    typeClass = PostgreSQLEnumType.class 
) 
public static class Post { 

    @Id 
    private Long id; 

    private String title; 

    @Enumerated(EnumType.STRING) 
    @Column(columnDefinition = "post_status_info") 
    @Type(type = "pgsql_enum") 
    private PostStatus status; 

    //Getters and setters omitted for brevity 
} 

यही है, यह एक आकर्षण की तरह काम करता है। यहां एक test on GitHub that proves it है।

संबंधित मुद्दे